28. 컴포넌트를 분리해야할 때는 언제일까?

const reactDescriptions = ['Fundamental', 'Core', 'Advanced'];

function genRandomInt(max) {
    return Math.floor(Math.random() * (max + 1));
}

function Header() {
    const description = reactDescriptions[genRandomInt(reactDescriptions.length - 1)];
    
    return (
        <header>
            <h1>{description}</h1>
        </header>
    );
}
import Header from "./Header";
import CoreConcepts from "./CoreConcepts";
import { CORE_CONCEPTS } from "./data";
import TabButton from "./TabButton";

function App() {
    const [selectedTopic, setSelectedTopic] = useState("components");
    
    function handleSelect(selectedButton) {
        setSelectedTopic(selectedButton);
        console.log(selectedTopic);
    }
    
    return (
        <div>
            <Header/>
            <main>
                <section id="core-concepts">
                    <h2>Core Concepts</h2>
                    <ul>
                        {CORE_CONCEPTS.map((concept) => (
                            <CoreConcepts key={concept.title} {...concept} />
                        ))}
                    </ul>
                </section>
                <section id="examples">
                    <h2>Examples</h2>
                    <menu>
                        <TabButton
                            isSelected={selectedTopic === "components"}
                            onSelect={() => handleSelect("components")}
                        >
                            Components
                        </TabButton>
                        <TabButton
                            isSelected={selectedTopic === "jsx"}
                            onSelect={() => handleSelect("jsx")}
                        >
                            JSX
                        </TabButton>
                        <TabButton
                            isSelected={selectedTopic === "props"}
                            onSelect={() => handleSelect("props")}
                        >
                            Props
                        </TabButton>
                        <TabButton
                            isSelected={selectedTopic === "state"}
                            onSelect={() => handleSelect("state")}
                        >
                            State
                        </TabButton>
                    </menu>
                </section>
            </main>
        </div>
    );
}

위 Root 컴포넌트 속에 많은 것이 포함되어 있는걸 볼 수 있다.
즉 위 Root 컴포넌트는 다양한 책임을 지고있다. 위 Root 컴포넌트의 역할이 CoreConcepts 컴포넌트를 렌더링하고, TabButton 컴포넌트를 렌더링하고, Header 컴포넌트를 렌더링하는 것이다.
이 모든걸 App 컴포넌트가 담당하고 있다.
그리고 state(상태)를 사용하여 상호작용 가능한 부분도 관리하고 있다.

이렇게 하나의 컴포넌트가 많은 책임을 지니고 있을 때, 이를 분리해야한다.

하나의 컴포넌트가 많은 책임을 지고 있을 때 발생할 수 있는 문제점은 다음과 같다.
App 컴포넌트 내부의 상태값 변화로 App 컴포넌트 함수가 실행되면, 그 안에 포함되어있는 컴포넌트들(예, Header) 모두 재실행된다.
이는 분명 낭비이므로 적절하게 컴포넌트를 분리해줘야된다.