[React] useEffect와 Side Effect - 2

SangHeon·2022년 12월 27일
0

[React]

목록 보기
3/8
post-thumbnail

useEffect를 사용하는 경우

React에서는 Functional Component에서
sideEffect를 효과적으로 관리하기 위해 useEffect 라는 Hook을 제공합니다.

함수형 컴포넌트의 경우 아래와 같은 기본 구조를 가지기에,
return문이 실행되어 JSX를 반환하기 전 실행되는 함수를 입력하면
Side Effect를 발생시킬 수 있게 됩니다.

(참조) (이전 포스팅) useEffect와 Side Effect - 1

export default function App() {
  console.log('Side Effect!!')
  
  return <h1>Hello World</h1>
}

그런데 위와같이 UI를 그려주는 렌더링 과정 전에 Side Effect를 발생시키면
두 가지 문제가 발생하게 됩니다.

렌더링 과정 전에 Side Effect가 발생하는 경우

  • Side Effect가 렌더링을 막습니다.
  • UI가 그려지는 렌더링 과정마다 Side Effect가 실행되게 됩니다.

그런데 리액트에서 제공하는 useEffect Hook을 사용하게 되면
위와같은 현상을 아래와 같이 바꾸어 줍니다.

useEffect Hook을 사용하여 Side Effect를 관리해주는 경우

  • 렌더링이 완료되고 난 후 side Effect를 발생시킬 수 있다.
  • 내가 원하는 경우에 따라 조건부로 렌더링을 실행할 수 있게 된다.

따라서 함수형 컴포넌트로 어플리케이션을 개발할 때 필요한 Side Effect를
효과적으로 관리하기 위해 우리는 useEffect Hook을 사용하는 것이 좋습니다.

useEffect의 사용법

useEffect는 리액트에서 제공해주는 Hook으로써,
컴포넌트가 렌더링 된 후, Side Effect가 실행되도록 만들어진 Hook입니다.
useEffect는 기본적으로 아래와 같은 방법으로 사용됩니다.

// useEffect(콜백 함수, 의존성 배열);

// 1. 의존성 배열이 존재하지 않으므로, 매 렌더링마다 useEffect가 실행된다.
useEffect(() => {
  // Side Effect 
  console.log('useEffect test 1')
})

// 2. 의존성 배열에 빈배열이 들어가있으므로, 렌더링시 1번만 useEffect가 실행된다. 
useEffect(() => {
  // Side Effect 
  console.log('useEffect test 1')
}, [])

// 3. 의존성 배열에 참조하는 state1, state2가 변경될 때 마다, useEffect 내부에 있는 side Effect를 실행시킨다.
useEffect(() => {
  // Side Effect 
  console.log('useEffect test 1')
}, [state1, state2])

우리는 useEffect를 사용하여
컴포넌트가 렌더링 된 후에 Side Effect를 일으킬 수 있으며,
조건에 따라(state가 변경되는 경우, 컴포넌트 마운트가 해제되는경우 등)
적절하게 Side Effect를 조절하여 사용할 수 있게 됩니다.

cleanUp

useEffect는 Side Effect를 clean up 할 수 있는 방법을 제공해주는데
사용법은 아래와 같습니다.

useEffect(() => {
  // Side Effect
  
  const cleanUpMethod = () => {
    // clean up 내용
  }
  return cleanUpMethod;
},[])

위의 기본 구조에서 useEffect는 2가지 경우에 useEffect 콜백함수 내부의 return문을 실행시켜주는데 2가지는 다음과 같습니다.

  • 다음 Side Effect를 발생시키기 전
    (의존성 배열에 state값이 존재하는 경우, state의 변경으로 인해
    Side Effect가 다시 발생되기 전)
  • 컴포넌트가 unmount 될 때
    (다른 페이지로 라우팅 되는 경우, 시간 초과에 따라 컴포넌트의 마운트가 해제되는 경우 등)

만약 useEffect의 의존성배열로 어떠한 state값이 들어가있고,
그 state가 변경됨에 따라 컴포넌트가 업데이트 된다고 가정했을 때 아래와 같이 실행 될 수 있습니다.

const [count, setCount] = useState();

useEffect(() => {
  // Side Effect
  console.log('useEffect SideEffect 1')
  
  return () => {
    // clean up 내용
    console.log('useEffect clean up 2')
  };
},[count])

return (
	<button onClick={e => setCount(prev => prev + 1)}>count 증가</button>
)

초기 렌더링이 완료 된 후 useEffect가 실행됨으로

    1. side Effect의 실행으로 console에
      'useEffect SideEffect 1' 가 나타나며

버튼을 클릭하여 state가 변경되는 경우

    1. state값이 변경된다
    1. useEffect 안의 return문이 실행되어 기존의 side Effect가 정리된다.
      (clean up)
    1. 기록된 side Effect가 다시 실행된다.

따라서 콘솔에는

// 초기 렌더링시
console.log('useEffect clean up 2') // 1

// 버튼 클릭 후 state 변경된 후
console.log('useEffect clean up 2') // 1
console.log('useEffect SideEffect 1') // 2

위와 같이 입력되게 된다.

결론

useEffect() Hook 내부에서 일어나는 일련의 과정을 이해함으로써
리액트의 라이프사이클을 이해할 수 있고, 조건에 맞는 렌더링을 개발자가 원하는 지점에서 작동시킬 수 있게 함으로써 어플리케이션의 품질을 향상 시킬 수 있다.

profile
Front-end Developer

0개의 댓글