React_15_useEffect

지원·2023년 9월 21일

React

목록 보기
16/71
post-thumbnail

페이지를 열었을 때 알아서 데이터를 불러오도록 만들려고 한다.

App 컴포넌트 함수를 실행하면 코드를 하나씩 실행하다가
handleLoad() 함수를 실행하게 되는데

이 함수는 비동기 함수이므로
현재 실행 중인 컴포넌트와는 별도로 실행되었다고 생각하면 된다.

그 다음 element를 구현하고 react는 화면을 그려준다.

여기서 handleLoad 함수의 동작을 보면
비동기로 리퀘스트를 보냈다가 response가 도착을 하면

reviews라는 변수를 지정하고
setitems를 통해서 state값을 변경해준다.

그럼 리액트는 App컴포넌트를 다시 랜더링하게 된다.
App 컴포넌트를 실행하게 된다.
이때 또 다시 handleLoad() 함수를 실행하게 되는데
state가 또 바뀌고 다시 랜더링되기 때문에

!!무한루프가 발생한다.!!

useEffect

이런 경우에 useEffect 함수를 사용하면 된다.

useEffect 함수에다가 실행할 콜백함수랑 빈 배열을 넘겨주게 되면
리액트는 콜백함수를 맨 처음 랜더링할 때만 실행하기 때문에
무한루프가 생기는 것을 방지할 수 있다.

컴포넌트가 처음 랜더링할 때 리퀘스트를 보내고 싶다면
useEffect를 사용한다.

정렬값이 바뀔 때마다 서버에서 데이터 가져오기

콜백함수는 리액트가 비동기로 실행할 함수이고
배열은 dependency list라고 부르는 값

useEffect를 호출하면 리액트는 곧바로 콜백함수를 실행하는 것이 아니라
콜백함수를 예약해두었다가 랜더링이 끝나고나면 실행해준다.
이 떄 dependency list도 같이 기억해준다.

콜백함수를 실행해서 handleLoad함수를 실행하면 state값이 변경되니까
다시 랜더링이 시작된다.
다시 랜더링이 시작하면서 컴포넌트 함수를 실행하고
useEffect함수도 다시 실행하게되는데
이번에는 dependency list에 있는 값들을 앞에서 기억한 값과 비교한다.

빈 배열일 경우에는 모든 값들이 같게 된다.
랜더링이 끝나고 나서 콜백함수는 실행되지 않는다.


배열값에 order를 넣어 확인해보면
한 번 리퀘스트를 보내고 베스트순, 최신순을 눌러보면
그 때마다 새로 리퀘스트를 보낸다.

useEffect는 맨 처음 랜더링이 끝나면 콜백함수를 실행해주고
그 다음부터는 dependency list를 비교해서
기억했던 값과 다른 경우에만 콜백함수를 실행시킨다.

? 뒤에다가 key value를 지정하는 것을 쿼리하고 한다.

fetch('https://learn.codeit.kr/0633/film-reviews?order=rating')

베스트순, 최신순을 누를 떄
즉, 정렬값이 바뀔 때마다 서버에서 데이터를 받아오도록 하려면

getReviews 컴포넌트에 초기값 order='createAt'을 넣어주고
order=${order}를 담는 query라는 변수를 만든다.
그리고 해당서버에 ?${query}를 넣어준다.

handleLoad에서 orderQuery를 getReviews(orderQuery) 해주고

useEffect 콜백함수 안에 handleLoad(order); -> order를 넣어준다.


베스트순을 누르면 ?order=rating으로 정렬된 값이 바뀐 데이터를 가지고 온다
최신순을 누르면 ?order=createAt으로 정렬된 값이 바뀐 데이터를 가지고 온다

연습해보기

dependency list에 [], [first], [first, second]를
넣어보면서 확인해본다.

import { useEffect, useState } from 'react';

function App() {
  const [first, setFirst] = useState(1);
  const [second, setSecond] = useState(1);

  const handleFirstClick = () => setFirst(first + 1);

  const handleSecondClick = () => setSecond(second + 1);

  useEffect(() => {
    console.log('렌더링 이후', first, second);
  }, []);

  console.log('렌더링', first, second);

  return (
    <div>
      <h1>
        {first}, {second}
      </h1>
      <button onClick={handleFirstClick}>First</button>
      <button onClick={handleSecondClick}>Second</button>
    </div>
  );
}

export default App;

0개의 댓글