Component 사이에서 State를 공유하는 방법
- 부모 Component에 state 정의
- state를 prop에 넣어 자식 component에 전달
- 자식들은 해당 state를 공유함
- 이런 경우, setState 함수를 내리지 않는 이상 자식에게 state를 바꿀 권한이 없어짐.
- prop으로 setState 함수를 보내야 자식에서 state를 변경할 수 있음.
Single Source of Truth
- 설계할 때, 각각의 고유한 state들을 가질 component를 선택해야 한다.
- 어떤 component에서 이 state를 소유하는 것이 맞는지 고민하기.
- 많은 자식에서 이 state가 필요한 경우 공통된 상위 부모에 state를 정의해야 함.
Controlled vs Uncontrolled Component
Controlled Component
- 중요한 정보의 근원이 부모에서 내려온 props인 경우.
- 부모가 모든 행위를 지시함.
Uncontrolled Component
- 본인이 가진 State가 중요한 정보의 근원인 경우.
- 부모는 자식의 state의 제어권이 없음.
의미
- 실제 상황에서는 두 정의가 섞여있는 component가 많다.
- 하지만 이렇게 두 성질로 component를 나누어 생각하면 설계에 도움이 된다.
State is tied to a position in the tree
- State는 component 안에 존재하지 않고, react에 존재함.
- UI tree의 어느 부분에 component가 있는지 보고, state와 연결함.
const counter = <Counter />;
return (
<div>
{counter}
{counter}
</div>
);
- 따라서, 이렇게 정의한다 한들 Conter Component는 separate 되어있다.
- UI Tree에서 다른 부분에 속하기 때문.
- 또, 이 말은 UI Tree에서 Component가 사라지면, state도 없어진다는 것을 의미함.
{showB && <Counter />}
- showB에 따라 Counter Component가 사라졌다가 나타나면, Counter의 state는 초기화됨.
- state는 UI Tree의 특정 position에 있는 component와 연결되기 때문에, componenet render가 끝나면 state도 완전히 사라짐.
- 똑같은 자리에 다른 componenet가 render되거나, 그 자리에 componenet가 사라지는 경우에 state도 같이 사라짐.
Same component at the same position preserves state
{isFancy ? (
<Counter isFancy={true} />
) : (
<Counter isFancy={false} />
)}
- 이 경우에는 같은 component가 같은 자리에 render되고, prop만 달라짐.
- 이런 경우에 UI tree의 같은 position에 같은 Component이므로 state가 보존됨.
- 추가로, function componenet 안에 function componenet를 정의하고 render하면 안 되는 이유도 여기에 있음.
- 매 번 render 될 때마다 코드가 재실행 되므로 함수가 매번 재정의됨.
- 재정의된 함수는 다른 주소값을 가지고, react는 이를 서로 다른 componenet로 인식함.
- 따라서 내부 function component의 state는 항상 초기화됨.
Resetting state at the same position
의도적으로 같은 위치의 같은 component의 state를 초기화하고 싶은 경우.
- UI tree에서의 component 위치를 바꿈
{isPlayerA ? (
<Counter person="Taylor" />
) : (
<Counter person="Sarah" />
)}
이건 같은 자리이기 때무에, state가 초기화되지 않고 유지됨.
{isPlayerA &&
<Counter person="Taylor" />
}
{!isPlayerA &&
<Counter person="Sarah" />
}
이건 다른 자리이기 때문에, Counter가 바뀔 때마다 초기화됨.
- Key 사용
- map 할 때 요소들에 사용된 key와 같은 요소임
- 사실 key는 react에서 모든 componenet를 구별할 수 있게 하는 요소임
- key는 globally unique하지 않다. parent component 아래에서 위치를 지정한다고 생각하면 됨.
- parent 아래 요소들에서만 unique하면 됨.
Preserving state for removed components
- 모든 component 우선 render하고, CSS로 hide
- 간단한 UI에서 잘 작동함.
- 많은 DOM node를 포함하며 큰 tree를 가진 경우, 느려질 수 있음.
- state를 부모 component로 lift up
- react state가 아닌, localstorage 같은 다른 소스를 사용.
출처
https://react.dev/learn/sharing-state-between-components
https://react.dev/learn/preserving-and-resetting-state