React Effect Hook

🐶·2021년 6월 28일
0

미니 과제

목록 보기
9/15

함수 내에서 어떤 구현이 함수 외부에 영향을 끼치는 경우 해당 함수는 Side Effect가 있다고 표현한다.

React의 함수 컴포넌트는, props가 입력 & JSX Element가 출력으로 나간다. 여기에는 그 어떤 Side Effect도 없으며, 순수 함수로 작동한다.

하지만 보통 React 애플리케이션을 작성할 때에는, AJAX 요청이 필요하거나, LocalStorage 또는 타이머와 같은 React와 상관없는 API를 사용하는 경우가 발생할 수 있다. 이는 React의 입장에서는 전부 Side Effect 이고, React는 Side Effect를 다루기 위한 Hook인 Effect Hook을 제공한다.

React 컴포넌트에서의 Side Effect

  • 타이머 사용 (setTimeout)
  • 데이터 가져오기 (fetch API, localStorage)

useEffect(함수)

useEffect(함수, [종속성1, 종속성2, ...])

useEffect는 컴포넌트 내에서 Side effect를 실행할 수 있게 하는 Hook 이다. useEffect의 첫번째 인자는 함수이고, 해당 함수 내에서 side effect를 실행하면 된다.

useEffect 함수가 실행되는 조건은?

  • 컴포넌트 생성 후 처음 화면에 렌더링(표시)
  • 컴포넌트에 새로운 props가 전달되며 렌더링
  • 컴포넌트에 상태(state)가 바뀌며 렌더링
    이와 같이 매 번 새롭게 컴포넌트가 렌더링될 때 Effect Hook이 실행된다.

useEffect의 두번째 인자는 배열이다. 이 배열은 조건을 담고 있다. 여기서 조건은 어떤 값의 변경이 일어날 때를 의미한다. 따라서, 해당 배열엔 어떤 값의 목록이 들어간다. 이 배열을 종속성 배열이라고 한다. 배열 내의 종속성1, 또는 종속성2의 값이 변할 때, 첫번째 인자의 함수가 실행된다. 배열 내의 어떤 값이 변할 때에만, (effect가 발생하는) 함수가 실행됩니다.

종속배열의 유무?

1. 빈 배열 넣기
useEffect(함수, [])

2. 아무것도 넣지 않기 (기본 형태)
useEffect(함수)

(2번) 기본 형태의 useEffect는 컴포넌트가 처음 생성되거나, props가 업데이트되거나, 상태(state)가 업데이트될 때 effect 함수가 실행된다.(위에서 설명한 3가지 조건)

반면에 (1번) 빈 배열을 useEffect의 두번째 인자로 사용하면, 이 때에는 컴포넌트가 처음 생성될때만 effect 함수가 실행된다. 대표적으로 처음 단 한번, 외부 API를 통해 리소스를 받아오고 더이상 API 호출이 필요하지 않을 때에 사용할 수 있습니다.

실습에 응용해보자

위와 같이 조건을 사용자가 도착지를 입력하면 그 도착지에 맞는 항공편 정보가 필터링되어 뜨는 것을 구현해보자.

  1. 사용자에 의하여 변동되는 그 정보(출발지 & 도착지)를 객체로 담고 이 객체를 하나의 state(여기서 변수명: condition)로 여긴다. 출발지는 default로 정해져 있고 도착지만 사용자가 입력한다. 따라서 이 state의 초기값은 departure 한개만 속성으로 가지고 있다. --> useState() 사용~!
const [condition, setCondition] = useState({
    departure: 'ICN'
  })
  1. 그리고 이 정보가 바뀔때마다 자체 필터링에 의해서 검색결과(flightList)가 바뀐다.
    필터링 기능을 담당하고 있는 함수(getFlight)는 React 컴포넌트와는 별개로 작동하므로, Side Effect로 볼 수 있다. Side Effect는 Effect Hook을 이용해 처리해야 한다. --> useEffect() 사용~!
    condition 조건이 바뀌면, Effect Hook에 의해 getFlight(condition) 함수가 호출되도록 만들었다.

또한 isLoading이라는 boolean값을 가지는 상태를 한 개 더 만들어, 로딩되고 있을 땐 Loadingindicator 자식컴포넌트가 실행되도록 Side Effect에 setIsLoading 함수를 추가해주었다. 필터링 함수의 전후로 setIsLoading을 설정해주어 보다 나은 UX를 구현할 수 있다.

useEffect(async() => {
    setIsLoading(true)
    setFlightList(await getFlight(condition))//필터링 조건이 되는 객체를 인자로 넣어줌 = [{}, {}, {}... ]
    //Promise 성공시,,, 항공편 목록의 상태를 바꿔주는 것이므로 async/await 비동기사용
    setIsLoading(false)
  }, [condition]); //검색조건이 바뀔때마다 useEffect 실행.

랜더링 해주는 파트를 아래와 같이 isLoading 상태에 따라 두 케이스로 나누었다.

{isLoading? <LoadingIndicator /> : <FlightList list={flightList} />} 

위 내용을 통하여 React에서
1. 자식컴포넌트에서의 어떤 이벤트가
2. 부모컴포넌트의 상태를 변경시키고
3. 그 상태가 변경되면서 다른 상태에 영향을 미치는 과정
을 공부해보았다.

추가적으로, hook을 쓸 때 주의할 점을 리액트 공식문서에서 찾아볼 수 있다. only 최상위레벨에서만 & only React 함수 내에서만 hook을 호출해야 한다.

profile
우당탕탕 개발일기📝🤖

0개의 댓글