글 작성자: 망고좋아
반응형

 

🎯 Hook Flow 이해하기 2 :: App - Child, Clean-up

  • 훅의 호출 타이밍을 알아보자!

 

📝 Hook의 호출 타이밍 - Clean-up 타이밍에 집중해서

const rootElement = document.getElementById('root');

const Child = () => {
    console.log("   Child render start");
    const [text, setText] = React.useState(() => {
        console.log("   Child useState");
        return "";
    });



    React.useEffect(() => {
        console.log("   Child useEffect, no deps");
        return () => {
            console.log("   Child useEffect [Cleanup], no deps");
        }
    })

    React.useEffect(() => {
        console.log("   Child useEffect, empty deps");
        return () => {
            console.log("   Child useEffect [Cleanup], empty deps");
        }
    }, [])

    React.useEffect(() => {
        console.log("   Child useEffect, [text]");
        return () => {
            console.log("   Child useEffect [Cleanup], [text]");
        }
    }, [text])



    function handleChange(event) {
        setText(event.target.value)
    }

    const element =  (
        <>
            <input onChange={handleChange} />
            <p>{text}</p>
        </>
    )

    console.log("   Child render end");
    return element;
};



const App = () => {
    console.log("App render start");

    // input 박스를 보여줄지 말지 알려주는 상태
    const [show, setShow] = React.useState(() => {
        console.log("App useState");
        return false
    });



    React.useEffect(() => {
        console.log("App useEffect, no deps");
        // 기존에 셋팅된 사이드 이펙트를 싹 지우고 새롭게 셋팅
        return () => {
            console.log("App useEffect [Cleanup], no deps");
        }
    })

    React.useEffect(() => {
        console.log("App useEffect, empty deps");
        return () => {
            console.log("App useEffect [Cleanup], empty deps");
        }
    }, [])

    React.useEffect(() => {
        console.log("App useEffect, [show]");
        return () => {
            console.log("App useEffect [Cleanup], [show]");
        }
    }, [show])




    function handleClick() {
        setShow((prev) => !prev); // true면 false, false면 true로
    }


    console.log("App render end");
    return (
        <>  
            <button onClick={handleClick}>Search</button>
            {show ? <Child /> : null}
        </>
    )
};

ReactDOM.render(<App />, rootElement);

hook flow

  • 첫 시작
    • App render start -> App useState -> App render end -> App useEffect
  • input창 활성화
    • App render start -> App render end -> Child render start -> Child useState -> Child render end -> App useEffect [Cleanup] -> Child useEffect -> App useEffect
  • input 입력 시
    • Child render start -> Child render end -> Child useEffect [Cleanup] -> Child useEffect
  • input창 비 활성화
    • App render start -> App render end -> Child useEffect [Cleanup] -> App useEffect [Cleanup] -> App useEffect
  • Child useEffect까지 다 실행되고 나서 App useEffect가 실행된다.

 

Clean-up을 사용하는 이유

  • useEffect가 한번 동작되고 다시 동작될 때 이전에 생성된 사이드 이펙트를 지우고 클린업 코드를 실행
  • 즉, 기존에 설정된 셋팅값을 지우고 초기 셋팅값으로 돌려놓기 위한 동작
  • 클린업은 처음에 실행되지 않는다.(useEffect가 한 번은 실행돼야지 클린업 코드가 실행된다.)

 

🏷 요약

  • useEffect -> render가 끝난 뒤
  • update시 -> useEffect clean up / useEffect
    • clean up이 먼저 실행되고 useEffect가 실행된다.
    • 부모-자식 관계에서 clean up이 먼저 일어나는 것은 부모이다.
  • dependency array -> 전달받은 값의 변화 있는 경우에만

 

📌 참고

 
반응형