Hook은 calss없이 state나 라이프사이클 같은 React의 기능을 사용할 수 있게 해줍니다.
useState는 상태 유지 값과, 그 값을 갱신하는 함수를 반환합니다.
const [state, setState] = useState(initialValue);
최초 렌더링에서 state
는 initialValue
와 같습니다.
setState
는
state
를 갱신할 때 사용하는 함수입니다. 새 state
를 받아 컴포넌트 리렌더링을 큐에 등록합니다.
다음 리렌더링에서 상태 값은 항상 갱신된 최신 state
입니다.
setState
에서 갱신하려는 값이 현재의 state
와 동일하다면 리렌더링을 건너뜁니다.
이러한
setStat
는 리렌더링시에도 변경되지 않음을 보장합니다.
useEffect나, useCallback 의존성 목록에 이 함수를 포함하지 않아도 되는 이유입니다.
이전 state
를 활용 다음 state
를 갱신할 때, 함수를 전달할 수 있습니다.
이 함수는 이전 값(현재 상태값)을 인자로 받아, 다음 갱신할 값을 반환합니다.
function counter({initialCount}) {
const [count,setCount] = useState(initialCount);
return (
<button onClick={()=>{setCount(prevCount => prevCount-1)}}>-</button>
{count}
<button onClick={()=>{setCount(prevCount => prevCount+1)}}>+</button>
)
}
setState
에 보낸 업데이트 함수가 현재 상태 값과 일치한다면, 리렌더링은 건너뜁니다.
클래스 컴포넌트의
setState
와 다르게, 기존 객체와 갱신 객체를 자동으로 합치지 않습니다.
객체 전개 연산자를 사용하여 직접 해야 합니다.
side effect(짧게 effects)는 부작용이란 뜻으로, 직접 요청되는 effect 외에 것을 말합니다.
Effect Hook 즉, useEffect
는 함수 컴포넌트에서 side effect를 수행하게 해줍니다.
React class의 ComponentDidMount
ComponentDidUpdate
ComponentWillUnmount
와 같은 목적입니다.
어떤 effect를 발생하는 함수를 인자로 받습니다.
useEffect
의 기본 동작은 모든 렌더링을 완료한 후 effect 합니다.
useEffect(didUpdate);
구독, 타이머 등 다른 side effect는 함수 컴포넌트 본문 안에서 허용되지 않습니다.
함수형 컴포넌트는 렌더링될 때, 함수가 다시 실행됩니다.
function Child(props) {
const timer = setTimeout(func,1000);
}
위 코드는 렌더링 마다, 타이머를 중첩되게 설정합니다.
대신, useEffect
를 사용합니다.
function Child(props) {
useEffect(()=>{
const timer = setTimeout(func,1000);
});
}
컴포넌트가 화면에서 제거될 때 정리해야하는 리소스가 생길 수 있습니다.
구독이나 타이머ID 같은 것입니다.
정리를 위해, 전달된 함수는 정리 함수를 반환할 수 있습니다.
function Child(props) {
useEffect(()=>{
const timer = setTimeout(func,1000);
return () => clearTimeout(timer)
});
}
정리 함수는 메모리 누수 방지를 위해 UI 컴포넌트를 제거하기 전에 실행됩니다.
컴포넌트가 여러번 리렌더링 될 때는, 다음 effect가 수행전에 이전 effect는 정리됩니다.
effect의 기본 동작은, 모든 렌더링 후에 effect를 발생합니다.
일부 값이 갱신될 때에만, 발생시킬 effect라면 모든 렌더링 후에 발생 시킬 필요가 없습니다.
이 때, useEffect
의 두 번째 인자를 전달합니다.
effect가 종속된 배열을 전달합니다.
useEffect(() => {
const subscription = props.source.subscribe();
return () => {
subscription.unsubscribe();
};
},[props.source]);
props.source
값이 변경될 때만 effect를 발생합니다.