Closed saemileee closed 1 year ago
안녕하세요, 수업 내용을 기반으로 궁금한 부분들을 여러 실험을 통해서 체화하려고 시도하고, 질문 하는 모습이 너무 좋네요 :)
질문 사항들에 대해 하나씩 답변드리겠습니다.
a는 오늘 수업에서의 ref.current를 의존성 배열에 안 넣는 이유와 동일하다고 보면 될 것 같습니다. a 함수는 App 컴포넌트의 리렌더링에 전혀 영향을 미칠 수 없는 값이기에 설령 변경이 되더라도, 리렌더링이 트리거 되지 않고, 따라서 useEffect 또한 재실행 될 수 없습니다. 따라서 a의 변경이 effect에 유의미한 영향을 미치지 못하기에, a 함수는 unnecessary denpendencies로 판단, 린트에서 경고를 출력해준다고 이해하시면 되겠습니다.
// moduleFn.ts
import { useState } from "react";
export default function moduleFn() {
function a() {
return 1;
}
return { a };
}
// app.tsx
import moduleFn from './moduleFn'
export default function App() {
const { a } = moduleFn();
useEffect(() => {
a()
}, [a]);
return ;
}
이 코드는 최초 렌더링 이후 effect 함수를 통해서 a 함수가 호출되지만, a 함수는 내부에서 state update를 수행하지 않기에, 다음 렌더링이 발생하지 않게 되고 따라서 이 코드는 무한루프가 발생하지 않습니다.
// useCustomHook.ts
import { useState } from "react";
export default function useCustomHook() {
const [state, setState] = useState(0);
function a() {
setState((prev) => prev + 1);
return 1;
}
return { state, a };
}
// app.tsx
import React, { useEffect } from "react";
import a from './useCustomHook'
export default function App() {
const { a } = useCustomHook();
useEffect(() => {
a()
}, [a]);
return ;
}
마찬가지의 이유로 위 코드는 a 함수가 state update를 수행하므로, 리렌더링이 발생, 리렌더링 이후에 a 함수 호출, 이후 state update, 렌더링이 반복되기에 무한루프에 빠진다고 볼 수 있습니다.
즉 모든 질문에서 핵심적으로 이해해야 되는 내용은 "useEffect가 호출되는 시점은 컴포넌트가 렌더링 되는 과정에서 호출된다." 입니다.
컴포넌트 렌더링과 useEffect의 흐름을 정리하자면
즉, state의 변경이 없어서 컴포넌트가 리렌더링 되지 않는다면 3~4에 해당하는 과정은 일어날 수 없다는 점을 이해하시면 헷갈렸던 부분들을 이해하실 수 있을겁니다.
도움이 되셨길 바라며, 추가적으로 궁금한 사항 있으시면 이어서 코멘트 달아주세요 :)
모듈화해서 임포트한 컴포넌트의 state를 사용하지 않더라도 해당 모듈 내에서 state가 바뀌면 해당 state를 컴포넌트에 직접적으로 사용하지 않더라도 의존성 배열의 값이 변경 되었다고 인지하고 리렌더링 되는군요! 많은 도움이 되었습니다 :) 정말 감사드립니다!
안녕하세요 멘토님 :) 지난 세션 useEffect 관련한 양질의 강의를 듣고 useEffect를 제대로 사용하지 못하고 있었던 지난 날을 반성하면서 여러 케이스를 테스트 해보며 체화하고 있던 중 몇 가지 궁금한 사항이 생겨 질문 드립니다.
1. 임포트한 함수를 useEffect 내부에서 쓸 경우 의존성 배열 명시
위의 경우 useEffect에서 사용하고 있는
a 함수
는 외부에서 호출하고 있습니다.지난 세션에서 예시로 말씀해 주신
props
에서setState
를 받아useEffect
내부에서 사용할 때 의존성 배열에 setState를 추가하는 것, 함수 컴포넌트를 바깥으로 이동시키고 사용하는 것과 동일한 맥락으로,a 함수
가 정적인 함수인지 app 컴포넌트 내에서는 확인할 수 없으니 의존성 배열에 a가 추가되어야할 것 같은데, 이 경우는 오히려 a를 명시하면 린트에서 경고 문구가 뜨더라구요.. 이유가 궁금합니다.2. 무한루프
1) 컴포넌트로 모듈화한 함수 사용 시 무한루프가 발생하지 않는 이유
위의 경우에는 모듈화 한
a
함수만 사용하여 useEffect를 실행하고 있습니다.이 경우 모듈 함수를 임포트 한 후 구조분해 할당으로 선언한
a 함수
를 컴포넌트가 렌더링 될 때 참조비교하여 다른 함수로 인식하고 무한루프가 발생할 것으로 예상하였는데 최초 한 번 실행 후 실행되지 않고 있습니다.2) state를 사용하지 않고 커스텀 훅을 사용할 경우 무한루프가 발생하는 이유
위 코드에서는 커스텀 훅 내부에서
a 함수
가state
를 세팅하고 있고,a 함수만
app 컴포넌트에서 재선언하여 사용하였는데 무한루프가 발생하였습니다.2-1) 번에서 추측한 내용을 바탕으로 위와 같은 코드에서도 App 컴포넌트 내에 변경될 상태가 없으니 커스텀 훅의 함수를 사용하더라도 최초 실행만 되고 마무리 될 줄 알았는데 위 코드에서는 무한루프가 발생하였습니다.
그래서.. 다시 한 번 실행 순서를 생각해보기로 했습니다..
다시 생각해 본 실행 순서..
2-1) 컴포넌트로 모듈화 한 함수 사용 (무한루프 X)
2-2) 커스텀 훅으로 모듈화한 함수만 사용 (무한루프)
위와 같이 추측하면 각 케이스에서 무한루프가 발생하거나 발생하지 않는 이유를 수긍할 수 있을 것 같은데요. 만약 위의 추측이 맞다면
이렇게 생각하더라도 2-1)의 실행 순서 4번에서는 a 함수의 참조값을 비교하기 때문에 useEffect가 재실행될 것 같은데.. 그렇지 않는 이유가 정말 궁금합니다..
복잡한 머리 속을 최대한 정리해 본 질문이지만 다소 가독성이 떨어지더라도 양해 부탁드립니다. 언제나 감사드립니다 🙇