정답: "toggle color" 버튼을 눌러도 count
값은 유지된다.
0
같은 위치에서의 동일한 컴포넌트는 상태가 유지된다.
리액트에서 useState
등을 통해 상태를 정의하면, 그 정보는 어디에 저장되는가? 우리는 이미 4번 문제에서 리액트를 직접 구현해보며 답을 찾았다. 상태는 컴포넌트가 아닌 React
안에 저장된다. 그래야 여러 번의 렌더링 사이에서도 상태가 초기화되지 않고 유지될 수 있었다.
우리는 컴포넌트가 하나 밖에 없는 경우를 구현하였지만, 실제로는 여러 컴포넌트들이 각각의 상태를 가질 수 있다. 리액트는 렌더 트리에서 각 컴포넌트들의 위치를 참고하여 상태값들을 올바른 컴포넌트에 제공한다. 때문에 어떤 컴포넌트의 상태가 리렌더링 이후에도 보존되기 위해서는 두 가지의 조건을 만족해야 한다.
- 동일한 컴포넌트
- 동일한 위치
여기서 위치는 root
를 기준으로 하는 일종의 상대 경로 생각하면 된다. 이번 문제의 코드를 다시 보자.
show
가 참이든 거짓이든 상관없이 <Counter/>
컴포넌트는 항상 root
의 - 첫 번째 자식(<div>
)의 - 첫 번째 자식(<Counter/>
)이다. 컴포넌트도 같고, 위치도 같다. 상태는 유지된다.
그러나 다음과 같은 컴포넌트는 상태가 유지되지 않는다. show
의 값에 따라 <Counter/>
의 위치가 바뀌기 때문이다.
0
show
값이 true
이면 <Counter/>
컴포넌트는 첫 번째 자리에 위치한다. show
값이 false
이면 두 번째 자리에 위치한다.
여기서
show
값이false
이면<Counter color="red" />
는 화면에 보이지 않는데, 어떻게 첫 번째 자리를 차지한다는 것일까? 이는 Babel을 통해 변환된 코드를 보면 이해가 쉽다.
show
값에 상관 없이React.createElement
함수의 몇 번째 인자냐에 따라 처음부터 위치가 결정되어 있었다!
위치는 동일하지만 컴포넌트가 바뀌면 어떻게 될까? 이 경우 리액트는 해당 컴포넌트와 그 하위 트리의 모든 상태를 초기화한다. 이를테면 아래의 컴포넌트는 매 클릭마다 <input/>
에 입력한 값이 초기화된다. 왜냐하면 매 렌더링마다 다른 <Input/>
컴포넌트가 생성되기 때문이다.