=> state 로 사용할 것, 그렇지 않은 것을 잘 구분할 필요가 있다. state 여야 하는지 꼭 반문해볼 것!
initial
또는 default
로 시작하여 새로운 값이 무시됨을 명확히 해야 한다.function Message({ initialColor }) {
// The `color` state variable holds the *first* value of `initialColor`.
// Further changes to the `initialColor` prop are ignored.
const [color, setColor] = useState(initialColor);
function List({ items }) {
const [isReverse, setIsReverse] = useState(false);
const [selection, setSelection] = useState(null);
// 🔴 피하세요: Effect에서 prop 변경 시 state 조정하기
useEffect(() => {
setSelection(null);
}, [items]);
// ...
}
function List({ items }) {
const [isReverse, setIsReverse] = useState(false);
const [selection, setSelection] = useState(null);
// 더 좋습니다: 렌더링 중 state 조정
const [prevItems, setPrevItems] = useState(items);
if (items !== prevItems) {
setPrevItems(items);
setSelection(null);
}
// ...
}
=> state 변경을 렌더링 중에 최대한 계산하기를 추천한다.
item 이 바뀔 때마다 selection 을 초기화 해주고 싶을 때, useEffect 에서 처리하지 말고 차라리 prevItem 을 저장하는 state 을 둬라
function List({ items }) {
const [isReverse, setIsReverse] = useState(false);
const [selection, setSelection] = useState(null);
// 더 좋습니다: 렌더링 중 state 조정
const [prevItems, setPrevItems] = useState(items);
if (items !== prevItems) {
setPrevItems(items);
setSelection(null);
}
// ...
}
React는 return
문으로 종료된 후 즉시 List
를 다시 렌더링 합니다.
⇒ return 문이 없는데 어디서 종료를 시킨다는 걸까?
렌더링 도중 컴포넌트를 업데이트하면 React는 반환된 JSX를 버리고 즉시 렌더링을 다시 시도합니다.
⇒ 반환된 JSX 를 버림
매우 느린 연속적 재시도를 피하기 위해 React는 렌더링 중에 동일한 컴포넌트의 state만 업데이트할 수 있도록 합니다. 렌더링 도중 다른 컴포넌트의 state를 업데이트하면 에러가 발생합니다.
⇒ store 등을 업데이트 시키면 안 되는듯..?
컴포넌트를 순수하게 유지하기 위해 DOM 변경이나 타임아웃 설정과 같은 다른 사이드 이펙트들은 이벤트 핸들러나 Effect에 남겨둬야 합니다.
탈출구에서 다루는 useEffect 관련 내용들을 학습하니 'useEffect 를 제대로 이해하고 사용한 것이 아니었구나' 라는 생각이 들었습니다.