CodeStates/React

[React] 데이터 흐름의 이해와 비동기 요청 처리

디스페어 2022. 4. 4.

React 데이터 흐름

  • React의 개발 방식 : 한가지 일만 하는 컴포넌트 단위로 시작(컴포넌트를 먼저 만들고 조립)
    *단일 책임 원칙, 상향식(bottom-up)

 

1. 단방향 데이터 흐름(one-way data flow)

  • 데이터의 흐름 : 컴포넌트는 컴포넌트 바깥에서 props를 이용해 데이터를 마치 인자(arguments) 혹은 속성(attributes)처럼 전달받음
  • 하향식(top-down) : 데이터를 전달하는 주체는 부모 컴포넌트
  • 컴포넌트는 props를 통해 전달받은 데이터가 어디서 왔는지 전혀 알지 못함

 

 

2. 역방향 데이터 흐름 추가하기

  • 부모 컴포넌트에서의 상태가 하위 컴포넌트에 의해 변하는 경우 존재
  • State 끌어올리기(Lifting state up) : 상태를 변경시키는 함수(handler)를 하위 컴포넌트에 props로 전달해서 해결
    *콜백 함수를 사용하는 방법과 비슷

 

 

3. Lifting state up

  • 상위 컴포넌트의 "상태를 변경하는 함수" 그 자체를 하위 컴포넌트로 전달하고, 이 함수를 하위 컴포넌트가 실행
  • props로 전달받은 함수를 컴포넌트 내에서 실행할 수 있게 됨
  • 여전히 단방향 데이터 흐름에 원칙에 부합

 

 

Side Effect와 Pure Function

1. Side Effect(부수 효과)

let foo = 'Despair'

function bar() {
  foo = 'Nightmarish'
}

bar(); 
// bar는 foo를 변경시켜 Side Effect를 발생
// 'Despair'가 'Nightmarish'로 변형
  • Side Effect : 함수 내에서 어떤 구현이 함수 외부에 영향을 끼치는 것

 

2. Pure Function (순수 함수)

function upper(str) {
  return str.toUpperCase();
  // Immutable : toUpperCase 메소드는 원본을 수정하지 않음
}

upper('hello') // 'HELLO'
  • 오직 함수의 입력만이 함수의 결과에 영향을 주는 함수로, 입력으로 전달된 값을 수정하지 않음
  • 함수의 입력이 아닌 다른 값이 함수의 결과에 영향을 미치는 경우, 순수 함수라 할 수 없음

 

2-1. 순수함수 조건

  • 예측 가능한 함수 : 동일한 인자가 들어갈 경우 항상 똑같은 값이 리턴됨을 보장
  • 네트워크 요청과 같은 Side Effect가 없어야 함
  • return 값으로만 소통

 

2-2. 순수함수가 아닌 것

  • Math.random() : 항상 다른 값이 나오기 때문에 예측이 불가능
  • fetch API를 이용해 AJAX 요청 : 네트워크 상황, 서버 상태에 따라 응답코드가 달라지기 때문에 예측이 불가능

 

3. React의 함수 컴포넌트

React 컴포넌트에서의 Side Effect
타이머 사용 (setTimeout)
데이터 가져오기 (fetch API, localStorage)
  • 입력 : props & 출력 : JSX Element
  • 그 어떤 Side Effect도 없으며, 순수 함수로 작동
  • AJAX 요청이 필요하거나, LocalStorage 또는 타이머와 같은 React와 상관없는 API를 사용하는 경우 Side Effect 발생
    *Side Effect를 다루기 위한 Hook : Effect Hook을 제공

 

 

Effect Hook

  • 컴포넌트 내에서 Side effect를 실행할 수 있게 하는 Hook
  • 주의할 점 : 최상위에서만 Hook을 호출, React 함수 내에서 Hook을 호출

 

1. Effect Hook 기본

useEffect(함수)
  • useEffect의 첫번째 인자는 함수
  • 새롭게 컴포넌트가 렌더링될 때 실행
    - 컴포넌트 생성 후 처음 화면에 렌더링(표시)
    - 컴포넌트에 새로운 props가 전달되며 렌더링
    - 컴포넌트에 상태(state)가 바뀌며 렌더링

 

2. Effect Hook 조건부 실행

useEffect(함수, [종속성1, 종속성2, ...])
  • 두 번째 인자 : 어떤 값의 변경이 일어날 때를 의미
    *해당 배열엔 어떤 값의 목록이 들어가며, 이 배열을 종속성 배열이라 함
  • 조건부 effect 발생(dependency array) : 종속성 배열 내의 어떤 값이 변할 때에만 함수가 실행

 

3. 단 한번만 실행되는 Effect 함수

useEffect(함수, [])
  • 빈 배열을 useEffect의 두 번째 인자로 사용 : 컴포넌트가 처음 생성될때만 effect 함수가 실행
  • 처음 단 한 번, 외부 API를 통해 리소스를 받아오고 더이상 API 호출이 필요하지 않을 때에 사용

 

 

컴포넌트 내에서 AJAX 요청

1. 컴포넌트 내에서 필터링

useEffect(() => {
  const result = getProverbs();
  setProverbs(result);
}, []);
  • 처음 단 한번, 외부 API로부터 명언 목록을 받아오고, filter 함수를 이용
  • HTTP 요청의 빈도를 줄일 수 있지만, 브라우저(클라이언트)의 메모리 상에 많은 데이터를 갖게 되므로, 클라이언트의 부담이 늘어남

 

2. 컴포넌트 외부에서 필터링

useEffect(() => {
  const result = getProverbs(filter);
  setProverbs(result);
}, [filter]);
  • 검색어가 바뀔 때마다, 외부 API를 호출
  • 클라이언트가 필터링 구현을 생각하지 않아도 되지만, 빈번한 HTTP 요청이 일어나게 되며 서버가 필터링을 처리하므로 서버가 부담을 가져감
반응형

댓글