리렌더링과 마운트, useEffect

sham·2022년 2월 3일
2

42world 개발일지

목록 보기
2/3
post-custom-banner

두줄 요약

useEffect(() ⇒ {}, [])가 실행되는 조건은 리렌더링이 아닌 마운트 될 때이다!

리렌더링이 되더라도 useEffect의 함수 부분은 실행되지 않는다!

리렌더링의 조건

대표적인 리렌더링의 조건으로는 다음이 있다.

  1. 컴포넌트의 state가 변했을 때
  2. props의 값이 변했을 때
  3. 부모 컴포넌트가 렌더링 되었을 때

[react] 리렌더링이 되는 조건들 살펴보기

useEffect

컴포넌트의 생명주기에 따른 동작을 제어해줄 수 있다.

useEffect(콜백 함수 or 익명 함수, [조건]);

사용할 때는 여러 가지 방법이 존재한다.

  1. useEffect(() ⇒ {})
    • state가 변경될 때마다 항상 실행된다.
  2. useEffect(() ⇒ {}, [])
    • 렌더링 될 때 한 번만 실행된다.
  3. useEffect(() ⇒ {}, [조건])
    • 조건이 변할 때마다 실행된다.
  • 리턴 값으로 넣은 콜백 함수는 컴포넌트가 언마운트 될 때, 값이 변하기 직전에 실행된다.

React hooks 리액트 훅 useEffect란?

React Hooks : useEffect() 함수

리액트 useEffect 개발자가 알아야 할 네가지 팁

이를 조합하면

state의 값을 변경 === 컴포넌트가 리렌더링 === useEffect(() ⇒ {}, [])가 실행된다고 생각했으나, 실제는 전혀 달랐다.

import { useState, useEffect } from 'react';

import Button from '@mui/material/Button';

const Child = ({ number, array }) => {
  useEffect(() => {
    console.log('child change');
  }, []);
  return (
    <div>
      num : {number}
      {array.map((e, i) => {
        return <div key={i}>temp</div>;
      })}
    </div>
  );
};

const MinePage = () => {
  const [stateNum, setStateNum] = useState(0);
  const [array, setArray] = useState(['str']);
  let normalNum = 0;

  useEffect(() => {
    console.log('parent change');
    console.log('array :', array);
    return () => {
      console.log('before change');
    };
  }, []);
  const handleNormal = () => {
    normalNum++;
    console.log(normalNum);
  };
  const handleState = () => {
    setStateNum(stateNum + 1);
    setArray(prev => {
      return ['str', ...prev];
    });
  };

  return (
    <div>
      <Button onClick={handleNormal}>일반 증가</Button>
      <Button onClick={handleState}>state 증가</Button>
      <Child number={stateNum} array={array} />
      nor : {normalNum}
    </div>
  );
};
export default MinePage;

state를 변경하였는데도 useEffect 내의 구문은 변경되지 않았다.

그럼에도 불구하고 state가 변경됨에 따라 컴포넌트가 보여주는 화면은 변하는데, 즉 리렌더링이 된다는 의미이므로 useEffect(() ⇒ {}, [])의 조건은 리렌더링이 아니라는 것을 알 수 있다.


마운트, 언마운트

마운트, 언마운트란?

마운트는 컴포넌트가 화면에 나타나는 것을 의미한다. 반대로 언마운트란 화면에서 삭제되는 것을 의미한다.

useEffect(() ⇒ {}, [])는 단 한 번 실행되고, 실행되는 조건은 컴포넌트가 마운트 될 때이다.

useEffect(() ⇒ {}, []) 로는 state를 변경하더라도 함수가 실행되지 않는 것이 정상적인 작동이었던 것이다.

import { useState, useEffect } from 'react';

import Button from '@mui/material/Button';

const Child = () => {
  useEffect(() => {
    console.log('child change');
  });
  return <div>hello</div>;
};

const MinePage = () => {
  const [stateNum, setStateNum] = useState(0);
  const [array, setArray] = useState(['str']);
  let normalNum = 0;

  useEffect(() => {
    console.log('parent change');
    console.log('array :', array);
    return () => {
      console.log('before change');
    };
  }, []);
  const handleNormal = () => {
    normalNum++;
    console.log(normalNum);
  };
  const handleState = () => {
    setStateNum(stateNum + 1);
    setArray(prev => {
      return ['str', ...prev];
    });
  };

  return (
    <div>
      <Button onClick={handleNormal}>일반 증가</Button>
      <Button onClick={handleState}>state 증가</Button>
      <Child number={stateNum} array={array} />
      nor : {normalNum}
    </div>
  );
};
export default MinePage;

위의 코드에서 자식 컴포넌트의 useEffect 부분의 def를 비워놓았다.

이 경우 컴포넌트가 리렌더링 될 때마다 함수를 실행할 것이다.

리렌더링의 조건은 크게 3가지로

  1. 컴포넌트 자신의 state가 변하거나
  2. 부모 컴포넌트로부터 받는 props가 변하거나
  3. 부모 컴포넌트가 리렌더링 될 때

리렌더링이 이루어지는데, 위의 코드에서 자식 컴포넌트 Child는 state도, props도 존재하지 않으나 부모 컴포넌트가 state가 바뀌어서 리렌더링 되는 시점에서 자식 컴포넌트인 Child도 리렌더링 되게 된다.

profile
씨앗 개발자
post-custom-banner

0개의 댓글