이것저것

라이프사이클 메소드 (함수형 / 클래스형) 본문

JS 프레임워크/React

라이프사이클 메소드 (함수형 / 클래스형)

곰태태 2020. 8. 3. 18:42
반응형
SMALL

 

라이프사이클은 크게 세 단계로 나눌수 있다.

 

클래스형

1. Mounting : 페이지가 처음 로딩될 때에는 다음과 같은 실행흐름을 갖는다.

  1) constructor() : 클래스형 컴포넌트에서 사용하는 생성자 함수를 뜻한다.

  2) static getDerivedStateFromProps : 이런게 있다는데 모름(상관없음)

  3) render() : 우리가 알고있는 그 렌더함수이다. (return문은 렌더 안에 들어있기 때문에 생략)

  4) componentDidMount() : 렌더가 완료된 뒤에 실행되는 함수이다.

 

 

실제 실행 결과

 


 

2. Updating : 컴포넌트가 업데이트 될 경우 다음과 같은 Update과정을 거친다

(이 중에서는 두가지만 보면 되기 때문에 나머지는 설명을 적지 않았다)

  1) static getDerivedStateFromProps()

  2) shouldComponentUpdate()

  3) render() : 상호작용으로 state가 업데이트되면 변경된 state적용하기위해서 다시 렌더가 실행된다.

  4) getSnapShotBeforeUpdate()

  5) componentDidUpdate : 렌더 된 후에 실행되는 함수로, 렌더가 끝난 뒤 실행되었으면 하는 내용을 적어주면 된다.

 

(실제 실행내용은 생략함)


 

3. Unmounting

 1) componentWillUnmount() : 사용자가 컴포넌트를 종료하거나 다른 페이지로 넘어갔을 경우 실행되는 함수로, 눈으로 확인하기는 어렵지만 제대로 실행이 된다고 한다.

(아마 실제 실행을 확인하려면 Route / Link 를 사용해야 할 것)

 

 

 

 

 

 

 

 

 

 


 

함수형 컴포넌트

 

함수형 컴포넌트에서는 componentDidMount / componentDidUpdate / componentWillUnmount

를 사용하기 위해 훅문법인 useEffect함수를 사용한다.

 

useEffect함수의 장점은 클래스형에서 사용하던 세개의 함수를 하나의 함수 내에서 모두 구현이 가능하다는데에 있다.

 


 

1) componentDidMount

useEffect함수의 두번째 인수로 빈 배열을 넣어주면, componentDidMount와 같은 기능을 수행한다.

useEffect(
  function(){},
  []
);

 


 

2) componentDidMount + componentDidUpdate

useEffect에 두번째 인수를 넣어주지 않으면 componentDidMount와 componentDidUpdate를 합쳐놓은 것과 같은 효과를 보인다. state뿐만 아니라 prop에도 접근 가능하다고 한다.

useEffect(() => {
    document.title = `You clicked ${count} times`;
    //여기서 count는 State이다.
  });

 


3) componentWillUnmount

하나의 useEffect함수에서 함수를 리턴시켜줄 수 있다. 여기서 리턴되는 함수가 컴포넌트가 언마운트 될 때 실행된다.

아래에서 리턴문은 마운트나 업데이트 될 경우에는 실행되지 않다가 언마운트 될 때 실행된다.

(편의상 이름을 적어주었지만 람다식이나 익명함수로 작성해도 된다.)

useEffect(() => {
    document.title = `You clicked ${count} times`;
    
    return function f1(){ blablabla }
  });

4) useEffect의 두번째 인수

 

모든 렌더링 이후 effect를 적용하거나 정리(언마운트얘기)하는 것은 성능저하를 발생시킬 수 있기 때문에 때로는 아래와 같은 방법으로 useEffect를 사용한다.

useEffect(() => {
  document.title = `You clicked ${count} times`;
}, [count]); // count가 바뀔 때만 effect를 재실행합니다.

선택적 인수인 두번째 인수로 배열을 넘긴다. 이 함수는 count의 값이 변경될 때에만 재실행되게 된다.

여기에는  state도 props도 들어갈 수 있다.

 

 

 

 

 


 

추가

 

https://ko.reactjs.org/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often

 

한가지 알아두어야 할 점이 있다.

 

useEffect함수에서 두번째 인수로 빈 배열을 넘겨주었다고 생각해보자.

이경우에 첫번째 인수에서 props나 state의 값을 사용하는 것은 안전하지 않다.

useEffect함수가 어떤값을 참조하는지 알기 어렵기 때문이다.

function Example({ someProp }) {
  function f1() {
    console.log(someProp);
  }

  useEffect(() => {
  f1();
  }, [] );
}

 

따라서 안전하게 사용하려면 아래처럼 배열에 사용하는 인수를 넣어주어야 한다.

function Example({ someProp }) {
  function f1() {
    console.log(someProp);
  }

  useEffect(() => {
  f1();
  }, [someProp] );
}

 

useEffect에 사용할 함수의 선언을 같이 넣어줌으로써 effect가 사용하는 함수들을 명확하게 눈으로 확인 가능하다.

아래 코드는 선언을 안에 넣어주고, 동시에 언마운트까지 구현한 예시이다.

 

function Example({ someProp }) {

  useEffect(() => {
    function f1() {
    console.log(someProp);
  }
  
  f1();
  
  return function(){}
  
  }, [someProp] );
}

 


 

 

 

만약 어떤 이유로 함수를 useEffect에 넣을 수 없는 경우가 있다면, 다른 옵션도 있다.

 

- 함수 자체를 컴포넌트 밖으로 빼는 경우 (아래 예시에서는 함수를 부모가 가지고 있고 자식에게 props로 넘겨주었다)

이 경우에는 컴포넌트의 props나 state를 참조하지 않아야한다.

또한 의존성목록에 있을 필요도 없다(뭔소리?)

 

아래 코드는 부모가 받은 props인 productId를  사용한 함수를 만들고,

useEffect처럼 두번째 인수로 참조한 인수를 배열로 적어준다.

그리고 이 함수를 자식컴포넌트의 props로 던져준다.

 

자식컴포넌트는 이 함수를 받아서 useEffect의 첫번째 인수에서 실행하고,

두번째 인수는 첫번째 인수로 받은 함수 자체를 배열로 참조하면된다.

 

function ProductPage({ productId }) {
  // ✅ 모든렌더마다 변하는 것을 피하기 위해 useCallback으로 감싼다
  const fetchProduct = useCallback(() => {
    // productID를 사용하는 코드들...
  }, [productId]); // ✅ 모든 useCallback 의존성이 지정완료되었다.
  
  return <ProductDetails fetchProduct={fetchProduct} />;
}

function ProductDetails({ fetchProduct }) {
  useEffect(() => {
    fetchProduct();
  }, [fetchProduct]); // ✅ 모든 useEffect의존성이 지정완료되었다.
  // ...
}

 

 


 Effect의 의존값이 너무 자주 바뀔때 사용할 수 있는 방법

setState를 함수로 감싸서 사용하는 이유 : https://jyk-record.tistory.com/288

 

 

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const id = setInterval(() => {
      setCount(c => c + 1); // ✅ 인수전달 받아와서 count값에 더이상 의존하지 않는다.
    }, 1000);
    return () => clearInterval(id);
  }, []); // ✅ 더이상 count값에 의존하지 않으므로, 빈 배열을 넘겨도 된다.

  return <h1>{count}</h1>;
}

 


참고로 useEffect함수는 한번만 사용할 수 있는것이 아니라 여러번 실행이 가능하다.

useEffect를 여러번 사용하면 서로 관련이 없는 로직을 분리할 수 있다.

반응형
LIST

'JS 프레임워크 > React' 카테고리의 다른 글

redirect  (0) 2020.08.03
리액트에서 axios 사용하기  (0) 2020.08.03
props / state / propTypes / map / 컴포넌트 key  (0) 2020.08.03
[React] 6/11  (0) 2020.06.11
[React] 6/10 Redux Flow, handleActions  (0) 2020.06.10
Comments