가운데에 컨텐츠를 넣고, 오른쪽에는 그 컨텐츠들의 제목 부분만 띄워준다.
그리고 오른쪽의 제목들을 누르면 그 컨텐츠로 이동하는 것을 짜볼 것이다!
-> 벨로그에 있는 이 기능과 같은 것이다
import React, { useState, useEffect } from 'react';
function App() {
const [sections, setSections] = useState<any>([]);
useEffect(() => {
const content =
'<p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4><p>p 태그 입니다.</p><h1>H1 입니다.</h1><h2>H2 입니다.</h2><h3>H3 입니다.</h3><h4>H4입니다.</h4>';
// h1, h2, h3, h4에 해당하는 내용만 오른쪽에 띄우게 할 것
const regex =
/<h1.*?>(.*?)<\/h1>|<h2.*?>(.*?)<\/h2>|<h3.*?>(.*?)<\/h3>|<h4.*?>(.*?)<\/h4>/gs;
// -> matchAll에서는 matches[0] : 일치한 전체 문자열 (<h1>h1입니다.<h1>) /
// matches[1], matches[2], matches[3], matches[4] : 캡쳐 그룹에 해당하는 일치한 부분 문자열 (h1입니다.)
const matches = [...content.matchAll(regex)];
// 따라서, matches[0]은 html에,다음 요소들은 각각 content에 저장시킨다.
const newSections = matches.map((match, index) => ({
id: `section-${index + 1}`,
html: match[0] || '',
content: match[4] || match[3] || match[2] || match[1] || '',
isActive: false,
ref: React.createRef(),
}));
setSections(newSections);
}, []);
const handleClick = sectionId => {
setSections(
sections.map(section =>
section.id === sectionId
? { ...section, isActive: true }
: { ...section, isActive: false },
),
);
const selectedSection = sections.find(section => section.id === sectionId);
console.log(selectedSection);
selectedSection?.ref?.current?.scrollIntoView({ behavior: 'smooth' });
};
return (
<div>
<div>
{/* section에 들어있는 것들 다 돌린다(본문 내용) */}
{sections.map(section => (
<div>
<div
style={{ backgroundColor: 'red' }}
onClick={() => handleClick(section.id)}
>
{section.content}
</div>
</div>
))}
{/* 제목에 해당하는 것들 돌린다 */}
{sections.map(section => {
if (section?.html.startsWith('<h1')) {
return (
<h1
style={{ color: section.isActive ? 'red' : 'black' }}
ref={section.ref}
id={section.id}
>
{section.content}
</h1>
);
} else if (section?.html.startsWith('<h2')) {
return (
<h2
style={{ color: section.isActive ? 'red' : 'black' }}
ref={section.ref}
id={section.id}
>
{section.content}
</h2>
);
} else if (section?.html.startsWith('<h3')) {
return (
<h3
style={{ color: section.isActive ? 'red' : 'black' }}
ref={section.ref}
id={section.id}
>
{section.content}
</h3>
);
} else {
return (
<p
style={{ color: section.isActive ? 'red' : 'black' }}
ref={section.ref}
id={section.id}
>
{section.content}
</p>
);
}
})}
</div>
</div>
);
}
export default App;