useEffect Flow

Bonggus·2021년 11월 1일
0

React

목록 보기
1/1
post-thumbnail

Console을 통해 렌더링과 useState, useEffect가 어떤 순서로 진행되는지 살펴보자

//parents
import { useState, useEffect } from 'react'
import { Child } from './Child';

export const HookFlow = () => {
  console.log('Render start');
  const [showInput, setShowInput] = useState(() => {
    console.log('useState');
    return false;
  }); 
  const handleClick = () => {
    setShowInput(prev => !prev);
  };

  useEffect(() => {
    console.log('useEffect No deps');
    return () => {
      console.log('[Clean up] No deps');
    }
  });
  useEffect(() => {
    console.log('useEffect Empty deps');
    return (() => {
      console.log('[Clean up] Empty deps');
    });
  }, []);
  useEffect(() => {
    console.log('useEffect [show]');
    return (() => {
      console.log('[Clean up] [show] deps');
    })
  }, [showInput]);

  return (
    <>
      <button onClick={handleClick}>Search</button>
      {showInput && (
        <Child />
      )}
      {console.log('Render end')}
    </>
  );
}
// child
import { SetStateAction, useEffect, useState } from "react";

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

  useEffect(() => {
    console.log('   Child use Effect No deps');
    return () => {
      console.log('   Child [clean up] No deps');
    }
  });
  useEffect(() => {
    console.log('   Child use Effect Empty deps');
    return () => {
      console.log('   Child [clean up] No deps');
    }
  }, []);
  useEffect(() => {
    console.log('   Child use Effect Empty [text]');
    return () => {
      console.log('   Child [clean up] [text] deps');
    }
  }, [text]);

  const handleChange = (e: { target: { value: SetStateAction<string>; }; }) => {
    setText(e.target.value);
  }
  const elem = (
    <>
      <input onChange={handleChange} value={text} />
      <p></p>
    </>
  );
  console.log('   Child render end');
  return (
    elem
  )
}

초기 렌더링


  1. Parent Render start ->
  2. Parent useState ->
  3. Parent Render End ->
  4. Parent useEffect No deps/Empty/[Somthing]
  • 렌더링 이후 useEffect가 실행된다.

Child 등장


  1. Parent Render start ->
  2. Parent Render End ->
  3. Child Render start ->
  4. Child useState ->
  5. Child Render end ->
  6. Parent UseEffect Cleanup No deps/[Something] ->
  7. Child useEffect No deps/Empty/[Somthing] ->
  8. Parent UseEffect No deps/[something]
  • Child 컴포넌트가 등장할 때도 부모가 먼저 렌더링된다.
  • 부모 렌더링이 끝나면 Child컴포넌트 렌더링이 시작된다
  • Child 렌더링이 끝나고, useEffect호출 이전에 부모컴포넌트에서 Cleanup과정이 일어난다
  • 부모 Cleanup이 끝나고 child useEffect가 일어난다
  • 그리고 마지막으로 부모 useEffect가 일어난다.

Child unmount


  1. Parent Render start ->
  2. Parent Render End ->
  3. Child UseEffect Cleanup No deps/empty/[Something] ->
  4. Parent UseEffect Cleanup No deps/[Something] ->
  5. Parent UseEffect No deps/[something]
  • child가 unmount될떄는 부모 렌더링이 먼저 실행되고 child에서 클린업 과정이 일어난다.
  • 그리고 useEffect전에 부모에서 클린업 작업이 실행된다.
  • 마지막으로 useEffect가 발생하고 렌더링 종료

useEffect Clean-up

  • 렌더링하기 전에 설정해 놓았던 side-Effect(부수효과)를 제거하는 작업
  • unmount 이전에 발생
  • 처음실행될떄는 불리지 않음
  • 한번이라도 useEffect가 등록되면, 그 뒤로 불리기 시작
  • rendering -> cleanup -> useEffect
profile
프론트엔드

0개의 댓글