[React] lifeCycle 제어하기 - useEffect

2022. 8. 3. 16:57React

1. useEffect 훅 이란?

컴포넌트가 렌더링 될 때 특정 작업을 실행할 수 있도록 하는 Hook이다.

 

side Effect

React 컴포넌트가 화면에 렌더링된 이후에 비동기로 처리되어야 하는 부수적인 효과들을 흔히 Side Effect라고 일컽습니다. 대표적인 예로 어떤 데이터를 가져오기 위해서 외부 API를 호출하는 경우, 일단 화면에 렌더링할 수 있는 것은 먼저 렌더링하고 실제 데이터는 비동기로 가져오는 것이 권장됩니다. 요청 즉시 1차 렌더링을 함으로써 연동하는 API가 응답이 늦어지거나 응답이 없을 경우에도 영향을 최소화 시킬 수 있어서 사용자 경험 측면에서 유리하기 때문입니다.

 

 

2. 선언방법

  • 첫번째 인자(effect)는 함수
  • 두번째 인자는 배열(deps)
import react, { useEffect } from "react";
useEffect(effect, [deps]);

만약에 deps 배열을 비우게 된다면, 컴포넌트가 처음 나타날때에만 useEffect 에 등록한 함수가 호출된다.

 

 

3. LifeCycle.js

import React, {useEffect, useState} from "react";

const LifeCycle = () => {
  const [count, setCount] = useState(0);
  const [text, setText] = useState("");

  useEffect(() => {
    console.log('mount')
  }, []);

  return (
    <div className="LifeCycle" style={{padding: 20, textAlign: "center"}}>
      <div>
        <h3>{count}</h3>
        <button onClick={() => setCount(count + 1)}> +</button>
      </div>
      <div>
        <input type="text" value={text} onChange={(e) => setText(e.target.value)}/>
      </div>
    </div>
  )
}

export default LifeCycle;

 

deps에 변경하고 싶은 값만 넣어서 변경할 수도 있다!  ( 변경감지 watch가 생각난다 )

  useEffect(() => {
    console.log('mount')
  }, []);

  useEffect(() => {
    console.log('update')
  })

  useEffect(() => {
    console.log(`카운트: ${count} 변경`)
  }, [count])

  useEffect(() => {
    console.log(`텍스트: ${text} 변경`)
  }, [text])
  useEffect(() => {
    console.log(`카운트: ${count} 변경`)
    if (count > 5) {
      alert("count가 5를 넘었습니다. 1로 초기화 합니다.")
      setCount(1);
    }
  }, [count])

 

 

 

4. Unmount 

import React, {useEffect, useState} from "react";

const UnmountTest = () => {
  return (
    <div className="UnmountTest">
        Unmount Testing Component
    </div>
  )
}

const LifeCycle = () => {
  const [isVisible, setIsVisible] = useState(false);
  const toggle = () => setIsVisible(!isVisible);

  return (
    <div className="LifeCycle" style={{padding: 20}}>
      <button onClick={toggle}>On / Off</button>
      { isVisible && <UnmountTest/> }
    </div>
  )
}

export default LifeCycle;
{ isVisible && <UnmountTest/> }

단락회로 평가에 의해, isVisible이 true면 뒤에꺼도 true가 되고

isVisible이 false면 뒤에꺼 신경쓸 필요가 없으니 보이지 않게됨.

 

 

 

mount와 unmount 시점을 알기 위해서는

import React, {useEffect, useState} from "react";

const UnmountTest = () => {
  useEffect(() => {
    console.log('mount')

    return () => {
      console.log('Unmount')
    }
  }, [])

  return (
    <div className="UnmountTest">
        Unmount Testing Component
    </div>
  )
}

const LifeCycle = () => {
  const [isVisible, setIsVisible] = useState(false);
  const toggle = () => setIsVisible(!isVisible);

  return (
    <div className="LifeCycle" style={{padding: 20}}>
      <button onClick={toggle}>On / Off</button>
      { isVisible && <UnmountTest/> }
    </div>
  )
}

export default LifeCycle;

단순히 useEffect에서 return으로 함수를 반환해주면 된다.

return으로 반환하는 함수는 컴포넌트가 사라질 때 실행됨.

 

 

5. Vue의 watch속성

// Vue.js
<template>
  <input v-model="myName"/>
</template>
<script>
export default {
  data() {
    return {
      myName: ''
    }
  },
  watch: {
    myName(newValue, oldValue) {
      console.log(`${oldValue}였다가 ${newValue}로 변경`)
    }
  }
}
</script>
// React.js

import  {useState, useEffect} from "react";

const react = () => {
  const [myName, setMyName] = useState('');
  
  useEffect(() => {
    console.log(myName)
  }, [myName])

  return (
    <input onChange={e => setMyName(e.target.value)}/>
  )
}

export default react;

 

참고

 

[Vue vs. React 비교] (4)vue에 watch가 있다면 react에는 useEffect가 있다

Vue Vue에서 watch의 역할은, 해당 데이터가 변경되었을때 이런 로직을 수행하도록 정해놓는 것입니다. 이런식으로 정해놓으면 input 입력창안에 어떤 입력이 들어와서 myName이 변경된다면, myName이 wa

imagineu.tistory.com