React의 데이터 흐름과 Effect Hook

EBinY·2021년 9월 6일
0

React 데이터 흐름

  • 단방향 데이터 흐름(one-way data flow) : 부모에서 자식으로, 데이터 흐름이 하향식(top-down), 컴포넌트는 props를 통해 전달받은 데이터의 출처를 알 수 없음

  • 데이터는 변하는 값과, 변하지 않는 값으로 분류,변하는 값인 상태(State), 상태는 최소화하는 것이 좋다. 상태가 많아질수록 애플리케이션은 복잡해짐, 하나의 상태를 기반으로 두 컴포넌트가 영향을 받는다면 이 때에는 공통 소유 컴포넌트를 찾아 그 곳에 상태를 위치, 어떤 컴포넌트에 데이터를 상태로 두어야 하는지 여부는 다음 세가지 질문을 통해 판단
    = 부모로부터 props를 통해 전달됩니까? 그러면 확실히 state가 아닙니다.
    = 시간이 지나도 변하지 않나요? 그러면 확실히 state가 아닙니다.
    = 컴포넌트 안의 다른 state나 props를 가지고 계산 가능한가요? 그렇다면 state가 아닙니다.

  • State 끌어올리기(Lifting state up): 하위 컴포넌트에서 부모의 상태를 바꾸는 상황을 해결하는 키워드, 상태를 변경시키는 함수(handler)를 하위 컴포넌트에 props로 전달해서 해결, 콜백 함수와 유사

  • 상태 변경 함수가 정의된 컴포넌트와, 상태 변경 함수를 호출하는 컴포넌트가 다름을 알 수 있다.

  • React로 사고하기
    = 목업으로 시작하기
    = 1단계: UI를 컴포넌트 계층 구조로 나누기
    = 2단계: React로 정적인 버전 만들기
    = 3단계: UI state에 대한 최소한의(하지만 완전한) 표현 찾아내기
    = 4단계: State가 어디에 있어야 할 지 찾기
    = 5단계: 역방향 데이터 흐름 추가하기
    = https://ko.reactjs.org/docs/thinking-in-react.html

Effect Hook

  • Side Effect (부수 효과) : 함수 내에서 어떤 구현이 함수 외부에 영향을 끼치는 경우

  • Pure Function (순수 함수) : 함수의 입력만이 함수의 결과에 영향을 주는 함수
    = 입력으로 전달된 값을 수정하지 않는다. 예측 가능한 함수, 임의의 전달 인자는 항상 똑같은 리턴 값을 보장해야함

  • React 애플리케이션을 작성할 때에는, AJAX 요청이 필요하거나, 타이머 사용(setTimeout)
    , 데이터 가져오기 (fetch API, localStorage) 등 React와 상관없는 API를 사용하는 경우가 발생할 수 있습니다. 이는 React의 입장에서는 전부 Side Effect 입니다. React는 Side Effect를 다루기 위한 Hook인 Effect Hook을 제공함

  • useEffect의 첫번째 인자는 함수입니다. 해당 함수 내에서 side effect를 실행하면 됩니다. 이 함수는 다음과 같은 조건에서 실행
    = 컴포넌트 생성 후 처음 화면에 렌더링(표시)
    = 컴포넌트에 새로운 props가 전달되며 렌더링
    = 컴포넌트에 상태(state)가 바뀌며 렌더링
    = 최상위에서만 Hook을 호출합니다
    = React 함수 내에서 Hook을 호출합니다.

  • 조건부 effect 발생 (dependency array)
    = useEffect의 두 번째 인자는 배열입니다. 이 배열은 조건을 담고 있습니다. 여기서 조건은 boolean 형태의 표현식이 아닌, 어떤 값의 변경이 일어날 때를 의미합니다. 따라서, 해당 배열엔 어떤 값의 목록이 들어갑니다. 이 배열을 특별히 종속성 배열이라고 부릅니다.
    = useEffect(함수, [종속성1, 종속성2, ...])
    = 배열 내의 어떤 값(종속성)이 변할 때에만, (effect가 발생하는) 함수가 실행
    = useEffect(함수) : 아무것도 넣지 않기, (기본 형태)에는 컴포넌트가 처음 생성되거나, props가 업데이트되거나, 상태(state)가 업데이트될 때 effect 함수가 실행
    = useEffect(함수, []) : 빈 배열 넣기, 컴포넌트가 처음 생성될때만 effect 함수가 실행

컴포넌트 내에서 AJAX 요청

  • Data Fetching: 필터링 예제 다시보기
    = 컴포넌트 내에서 필터링: 전체 목록 데이터를 불러오고, 목록을 검색어로 filter 하는 방법
    = 컴포넌트 외부에서 필터링: 컴포넌트 외부로 API 요청을 할 때, 필터링한 결과를 받아오는 방법 (보통, 서버에 매번 검색어와 함께 요청하는 경우가 이에 해당합니다)
    = 컴포넌트 내부에서 처리
    (장)HTTP 요청의 빈도를 줄일 수 있다
    (단)브라우저(클라이언트)의 메모리 상에 많은 데이터를 두어, 클라이언트의 부담이 늘어난다
    = 컴포넌트 외부에서 처리
    (장) 클라이언트가 필터링 구현을 생각하지 않아도 된다
    (단) 빈번한 HTTP 요청이 일어나게 되며, 서버가 필터링을 처리하므로 서버 부담이 가중됨

  • AJAX 요청을 보냅시다!
    = fetch API를 써서, 서버에 요청
    = 외부 API 접속이 느릴 경우를 고려, 로딩 화면(loading indicator)의 구현은 필수
    = 기본적으로 Loading indicator의 구현도 상태 처리가 필요
    = fetch 요청의 전후로 setIsLoading을 설정해주어 보다 나은 UX를 구현
    = 클라이언트가 서버에 요청을 덜 보내는 방법: https://webclub.tistory.com/607
    = 서버가 클라이언트에게 돌려줄 응답을 캐싱하는 방법: https://developer.mozilla.org/ko/docs/Web/HTTP/Caching

0개의 댓글