React_데이터 흐름과 비동기 처리

hoony0802·2021년 5월 29일
0

React

목록 보기
3/5
post-thumbnail

React의 데이터 흐름

데이터는 위에서 아래로 흐름(하향식 top-down) - 단방향

데이터를 전달하는 주체는 부모 컴포넌트이고 props를 사용해 데이터를 마치 인자(arguments) 혹은 속성(attributes)처럼 전달한다.

컴포넌트는 props를 통해 전달받은 데이터가 어디서 왔는지 전혀 알지 못하고 전달받은 데이터의 형태 혹은 타입이 무엇인지만 알 수 있다.

변하는 데이터 값은 상태(state)
=> 상태가 많아질수록 애플리케이션은 복잡해지기 때문에 최소화하는게 Best

부모로부터 props를 통해 전달되거나 시간이 지나도 변하지 않거나 컴포넌트 안의 다른 stateprops를 가지고 계산 가능하면 상태(state)가 아니다.

두 개의 자식 컴포넌트가 하나의 상태에 접근하고자 할 때는 두 자식의 공통의 부모 컴포넌트에 상태를 위치한다.

Lifting State Up

자식의 상태가 부모의 상태에 영향을 끼칠 때 역방향 데이터 흐름 같아 보이지만 상태(state) 끌어 올리기를 통해 단방향 데이터 흐름 원칙에 부합한다.

상태 끌어 올리기에서는 상태 변경 함수가 정의된 컴포넌트와 상태 변경 함수를 호출하는 컴포넌트가 다르다.
=> 상태를 변경시키는 함수(handler)를 하위 컴포넌트에 props로 전달하고 이 함수를 하위 컴포넌트가 실행한다.

Effect Hook

Side Effect

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

Side Effect와 반대되는 순수 함수는 오직 함수의 입력만이 함수의 결과에 영향을 주는 함수를 의미하고 입력으로 전달된 값을 수정하지 않는다.

순수 함수의 특징 중 하나는 어떠한 전달 인자가 주어질 경우 항상 똑같은 값이 리턴됨을 보장해서 예측 가능한 함수이다.

Side Effect 예시

  • Math.random()
  • 어떤 함수가 fetch API를 사용한 AJAX 요청
  • LocalStorage 또는 타이머와 같은 React와 상관없는 API

useEffect

useEffect는 컴포넌트 내에서 Side effect를 실행할 수 있게 하는 Hook

useEffect 첫번째 인자(함수)

useEffect의 첫번째 인자는 함수이고 해당 함수 내에서 side effect를 실행

실행 조건

  • 컴포넌트 생성 후 처음 화면에 렌더링(표시)
  • 컴포넌트에 새로운 props가 전달되며 렌더링
  • 컴포넌트에 상태(state)가 바뀌며 렌더링

이와 같이 매 번 새롭게 컴포넌트가 렌더링될 때 Effect Hook이 실행됨

Hook 사용 주의사항

  • 최상위에서만 Hook을 호출
  • 오직 React 함수 내에서 Hook을 호출

useEffect 두번째 인자(종속성 배열)

useEffect의 두번째 인자인 배열의 조건은 boolean 형태의 표현식이 아닌 어떤 값의 변경이 일어날 때를 의미하고 해당 배열엔 어떤 값의 목록이 들어가고 이 배열을 종속성 배열이라한다.

useEffect(함수, [종속성1, 종속성2, ...])
배열 내의 종속성1, 또는 종속성2의 값이 변할 때 첫번째 인자의 함수가 실행
=> 배열 내의 어떤 값이 변할 때에만 (effect가 발생하는) 함수가 실행됨

useEffect의 두번째 인자인 종속성 배열에 따른 결과

  1. 종속성 배열이 빈 배열 일 때 : useEffect(함수, [])
    컴포넌트가 처음 생성될때만 effect 함수가 실행됨
    => 처음 단 한번 외부 API를 통해 리소스를 받아오고 더이상 API 호출이 필요하지 않을 때에 사용

  2. 종속성 배열이 없을 때 : useEffect(함수)
    기본 형태의 useEffect는 컴포넌트가 처음 생성되거나 props가 업데이트되거나 상태(state)가 업데이트될 때 effect 함수가 실행됨

컴포넌트 내에서 AJAX 요청

  1. 컴포넌트 내에서 필터링 : 전체 목록 데이터를 불러오고 목록을 검색어로 filter 하는 방법
    => 처음 단 한번만 외부 API로부터 목록을 받아오고 filter 함수를 사용
  1. 컴포넌트 외부에서 필터링 : 컴포넌트 외부로 API 요청을 할 때에 필터링한 결과를 받아오는 방법 (보통 서버에 매번 검색어와 함께 요청하는 경우가 이에 해당)
    => 검색어가 바뀔 때마다 외부 API를 호출

두 방식의 장단점

장점단점
컴포넌트 내부에서 처리HTTP 요청의 빈도를 줄일 수 있다브라우저(클라이언트)의 메모리 상에 많은 데이터를 갖게 되므로 클라이언트의 부담이 늘어난다
컴포넌트 외부에서 처리클라이언트가 필터링 구현을 생각하지 않아도 된다빈번한 HTTP 요청이 일어나게 되며 서버가 필터링을 처리하므로 서버가 부담을 가진다

AJAX 요청(외부 API 접속)이 매우 느릴 경우

const [isLoading, setIsLoading] = useState(true);

return {isLoading ? <LoadingIndicator /> : <div>로딩 완료 화면</div>}

useEffect(() => {
  setIsLoading(true);
  fetch(`API Endpoint?q=${filter}`)
    .then(resp => resp.json())
    .then(result => {
      setProverbs(result);
      setIsLoading(false);
    });
}, [filter]);

로딩 화면(loading indicator)의 구현은 필수적이며 로딩 화면 구현도 상태 처리 필요

profile
둔필승총(鈍筆勝聰) - 기억보다는 기록을

0개의 댓글