useEffect(() => {
if(status==="completed" && !error){
onAddedComment();
}
}, [status, error, onAddedComment]);
이 컴포넌트의 상위 컴포넌트에 state가 변경되었음을 알려야할 때
이 컴포넌트가 로드되거나 변경될 때마다 코멘트를 가져오도록 리퀘스트를 보낼 때
데이터를 가져올 때 함께 요청을 초기화하고 요청을 전송하며 로딩 상태와 오류 상태를 관리할 때
const {quoteId} = params;
useEffect(() => {
sendRequest(quoteId);
}, [sendRequest, quoteId]);
이는 파라미터가 변경될 때마다 이 효과가 다시 실행된다는 뜻이다.
위 코드에서는 파라미터가 하나뿐이지만, 만약 더 많은 파라미터가 있다면 원하지 않은 결과를 얻을 수 있다.
따라서 가능한 한 정확하게 객체 구조 분해를 사용하는 것이 확실히 좋다.
또한 위처럼 쓴다면 의존성에 전체로 params를 추가해야 한다.
이때 effect의 불필요한 재실행을 막기 위해 아래처럼 쓰는 것이 좋다.
useEffect(() => {
sendRequest(params.quoteId);
}, [params]);
const addedCommentHandler = useCallback(() => { });
{isAddingComment && <NewCommentForm quoteId={quoteId} onAddedComment={addedCommentHandler}/>}
useEffect(() => {
if(status==="completed" && !error){
onAddedComment();
}
}, [status, error, onAddedComment]);
addedCommentHandler가 onAddedComment prop을 통해 새 코멘트 폼으로 전달되기 때문이다.
그리고 거기에서 그 prop을 effect에 대한 의존성으로 사용했다.
useCallback을 사용하지 않으면, 여기서 사용한 함수는 결국 상위 컴포넌트가 다시 렌더링될 때마다 다시 생성될 것이다.
당연 그런 일은 피해야한다.
따라서 useCallback으로 래핑하는 게 중요하다. 그래서 불필요한 재렌더링 주기와 무한 루프를 방지하는 것이다.