<aside> 👉 실험에 쓰인 코드는 여기
</aside>
과연 전역 상태를 쓰는 게 맞는 것인가
라는 고민을 항상 해왔고, 그럴 때마다 내린 결론은 props로 내리자
였다.react가 권장하는 문법이 useState로 하나의 컴포넌트 내의 상태를 자유롭게 관리하는 것으로 알고 있는데 이 관리 방법을 다른 컴포넌트로 위임하는 게 별로다. useState의 state는 호출한 컴포넌트만을 위한 것이지 setState를 다른 컴포넌트로 전달해 이리저리 해당 state를 컨트롤하게 하고 싶지 않다.
props으로 전달하면서 생기는 불필요한 코드들. 예를 들어 setState를 전달한 컴포넌트에서 가장 상위에 있는 scope에서 사용하려 하면 오류가 난다.
// 예를 들면 이렇게
export const TypeOne = ({ setDataLength }: Props) => {
if(!typeOneData.length) {
setDataLength(0);
}
return (
<ul>
{typeOneData.length &&
typeOneData.map((d) => (
<div key={d.id}>
<li>{d.content}</li>
<li>{d.isLiked ? "like" : "hate"}</li>
<li>{d.userName}</li>
</div>
))}
{!typeOneData.length && <Empty />}
</ul>
);
};
왜냐하면 setState가 아직 전달되기 전에 불렸기 때문이다. 이럴 때 쓰는 방법이 useEffect!
// 써보면 더 가관이다
export const TypeOne = ({ setDataLength }: Props) => {
useEffect(() => {
setDataLength(typeOneData.length);
}, [typeOneData, setDataLength]);
return (
<ul>
{typeOneData.length &&
typeOneData.map((d) => (
<div key={d.id}>
<li>{d.content}</li>
<li>{d.isLiked ? "like" : "hate"}</li>
<li>{d.userName}</li>
</div>
))}
{!typeOneData.length && <Empty />}
</ul>
);
};
지금은 예시 코드라 괜찮아보일지 몰라도 코드가 복잡해지면서 상태도 더 추가되고 점점 더 지저분해지는 걸 느낀다.
// 이런 느낌
return (
<Header tab={tab} />
<div>
<button onClick={() => setTab("tab1")}>tab1</button>
<button onClick={() => setTab("tab2")}>tab2</button>
</div>
{tab === "tab1" && <TabOne />}
{tab === "tab2" && <TabTwo />}
)
방법 b; tab을 전환할 때마다 데이터 호출
방법 b; 최초 렌더시 데이터 호출