function App() {
const [terms, setTerms] = useState(false);
const acceptTerms = () => {
setTerms(true);
};
return (
<>
<label>
<input type="checkbox" onChange={acceptTerms()} /> Accept the Terms
</label>
</>
);
}
렌더링 -> acceptTerms 즉시 호출 -> 리렌더링 -> acceptTerms 즉시 호출이 반복되어 무한 렌더 루프에 빠진다.
<input type="checkbox" onChange={acceptTerms} />
그렇기에 이러한 방식으로 변경해준다.
function App() {
const [views, setViews] = useState(0);
useEffect(() => {
setViews(views + 1);
}, [views]);
return <>Some content</>;
}
위의 useEffect의 경우 view가 변할 때 실행 되는데 useEffect가 실행되면 view값이 변하고 view값이 변하면 useEffect가 실행되는 것이 반복되어 무한루프에 빠지게 된다.
useEffect(() =>{
setViews((v) => v+1);
},[]);
이러한 형식으로 종속성 배엘에서 변수를 제거하거나
function App() {
const [views, setViews] = useState(0);
const [isInitialRender, setIsInitialRender] = useState(true);
useEffect(() => {
if (isInitialRender) {
setIsInitialRender(false);
setViews(v + 1);
}
}, [views, isInitialRender]);
return <>Some content</>;
}
종속성 배열을 정리할 수 없는 경우 다시 실행할지 여부를 제한하는 추가 변수를 종속성 배열에 추가 하여 해결 할 수 있다.
function App() {
const [views, setViews] = useState(0);
const incrementViews = () => {
setViews((v) => v + 1);
};
useEffect(() => {
incrementViews();
}, [incrementViews]);
return <>Some content</>;
}
incrementViews의 경우 모든 렌더에서 동일한 기능인 것처럼 보이지만 실제로는 각 렌더에서 메모리에 새로운 기능이 생성된다.
useEffect(() => {
const incrementViews = () => {
setViews((v) => v + 1);
};
incrementViews();
}, []);
따라서 함수 선언을 useEffect안으로 옮기거나
const incrementViews = useCallback(() => {
setViews((v) => v + 1);
}, []);
useCallback을 이용하여 종속성 배열의 변수가 변경되지 않는 한 새 함수를 생성하지 않게 한다.