Unit9 - [React] 클라이언트 Ajax 요청

예진·2022년 10월 13일
0

🔥 React 데이터 흐름

  • 상향식(bottom-up)으로 앱을 만든다. => 테스트가 쉽고, 확장성이 좋다.
    React는 페이지가 아닌 컴포넌트 단위로 개발을 하며, 페이지를 만들기 전에 컴포넌트를 만든다.

1. React 데이터 흐름

React는 단방향 데이터 흐름(One-way data flow)을 따른다.

  • 데이터는 위에서 아래로(하향식, top-down) 흐른다.
    컴포넌트는 컴포넌트 바깥에서 props를 이용해 데이터를 마치 전달인자(arguments), 속성(attribute)처럼 전달받을 수 있다. => 데이터를 전달하는 주체는 부모 컴포넌트가 된다.

- 데이터 정의

아래 세 가지에 해당된다면 state가 아니다.

  1. 부모로부터 props를 통해 전달된다.
  2. 시간이 지나도 변하지 않는다.
  3. 컴포넌트 안의 다른 state나 props를 가지고 계산이 가능하다.

2. State 끌어올리기 (Lifting State Up)

: 상위 컴포넌트의 "상태를 변경하는 함수" 그 자체를 하위 컴포넌트로 전달하고, 이 함수를 하위 컴포넌트가 실행하는 방법


🔥 Effect Hook

1. Side Effect (부수 효과)

함수 내에서 어떤 구현이 함수 외부에 영향을 끼치는 경우 해당 함수는 Side Effect가 있다고 한다.
-> React 컴포넌트 내에서 fetch를 사용해 API 정보를 가져오거나 이벤트를 활용해 DOM을 직접 조작하는 경우

( React는 Side Effect를 다루기 위한 Hook인 Effect Hook을 제공한다. )

Pure Function (순수 함수)

: 오직 함수의 입력만이 함수의 결과에 영향을 주는 함수 (입력으로 전달된 값을 수정하지 않음)

순수 함수에는 네트워크 요청과 같은 Side Effect가 없다.
- 어떠한 전달 인자가 주어질 경우, 항상 똑같은 값이 리턴됨을 보장한다. => 예측 가능한 함수

+ Math.random() 은 0과 1 사이의 난수를 리턴하며 예측이 불가능하므로 순수 함수가 아니다.

2. Effect Hook 기본

useEffect(함수)

: 컴포넌트 내에서 Side effect를 실행할 수 있도록 하는 Hook

  • 첫 번째 인자 : 함수 ( 함수 내에서 Side effect를 실행하면 안됨 )
useEffect(() => {
	console.log(몇 번 호출될까요?)  // 컴포넌트가 처음 생성될 때 함수 실행
},[])
  • effect hook의 함수가 실행되는 조건
    - 컴포넌트 생성 후 처음 화면에 렌더링(표시)
    - 컴포넌트에 새로운 props가 전달되며 렌더링
    - 컴포넌트에 상태(state)가 바뀌며 렌더링

=> 매번 새롭게 컴포넌트가 렌더링 될 때 Effect Hook 실행

+ Hook 사용시 주의점 : 최상위에서만 Hook을 호출, React 함수 내에서 Hook을 호출

3. Effect Hook 조건부 실행

dependency array : effect hook의 첫 번째 인자인 함수가 실행되는 조건을 담고 있는 두 번째 인자

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

  • 두 번째 인자 : 종속성 배열
    ( 종속성 배열은 반드시 존재하지는 않아도 되며, 배열 내의 어떤 값이 변할 때에만 함수 실행)
    boolean 형태의 표현식이 아닌, 어떤 값의 변경이 일어날 때의 조건을 가진다.

- 단 한번만 실행되는 Effect 함수

  1. 빈 배열 넣기
    useEffect(함수, [])
    : 컴포넌트가 처음 생성될 때만 effect 함수 실행 ( 외부 API를 통해 리소스를 받아오고 더 이상 API이 필요하지 않을 때 사용

  2. 아무것도 넣지 않기 ( 기본 형태 )
    useEffect(함수)
    : 처음 생성되거나, props가 업데이트되거나, 상태(state)가 업데이트 될 때 effect 함수 실행

4. 컴포넌트 내에서의 Ajax 요청

Data Fetching

  1. 컴포넌트 내에서 필터링 : 전체 목록 데이터를 불러오고, 목록을 검색어로 filter 하는 방법
  2. 컴포넌트 외부에서 필터링 : 컴포넌트 외부로 API 요청을 할 때, 필터링한 결과를 받아오는 방법 ( 서버에 매번 검색어와 함께 요청하는 경우 )

두 방식의 차이점

AJAX 요청

ex) fetch API를 써서, 서버에 요청하는 코드 작성

useEffect(() => {
  fetch(`http://서버주소/proverbs?q=${filter}`)
    .then(resp => resp.json())
    .then(result => {
      setProverbs(result);
    });
}, [filter]);

외부 API 접속이 느릴 경우를 고려해 로딩 화면(loading indicator)의 구현은 필수적이다.

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

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

로딩 화면(loading indicator)에서도 상태 처리가 필요하다.

useEffect(() => {
  setIsLoading(true);
  fetch(`http://서버주소/proverbs?q=${filter}`)
    .then(resp => resp.json())
    .then(result => {
      setProverbs(result);
      setIsLoading(false);
    });
}, [filter]);

fetch 요청의 전후로 setIsLoading을 설정해 주어 보다 나은 UX를 구현할 수 있다.

profile
😊

0개의 댓글