TIL 34일차 - [React] 클라이언트 Ajax 요청 1

Yoon Kyung Park·2023년 5월 29일
0

TIL

목록 보기
34/75
  • React에서의 데이터 흐름, 단방향 데이터 흐름을 이해할 수 있다.

    o
    React에서 데이터는 부모 컴포넌트가 주체가 되어 props를 통해 하위 컴포넌트로 전달한다. 따라서 데이터는 위에서 아래로 하향식 방향인 단반향 데이터 흐름의 원칙을 따른다.

  • 어떤 컴포넌트에 state가 위치해야 하는지 알 수 있다.

    o
    컴포넌트 내에서 변하는 값인 상태(state)가 특정 컴포넌트에 영향을 준다면, 해당 컴포넌트에 상태를 위치시키면 된다.
    그러나 하나의 상태가 두 컴포넌트에 영향을 준다면, 두 컴포넌트의 상위 컴포넌트인 부모 컴포넌트에 상태를 위치시켜 하위 컴포넌트로 데이터가 전달되도록 한다.

  • State 끌어올리기의 개념을 이해할 수 있다.

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

      o
      상태 변경 함수가 정의된 컴포넌트는 상위 컴포넌트이며,
      상태 변경 함수를 호출하는 컴포넌트는 하위 컴포넌트다.

      React에서는 부모 컴포넌트에서 자식 컴포넌트로 데이터가 전달된다.
      그러나 부모 컴포넌트에서의 상태가 자식 컴포넌트에 의해 변하는 경우가 있다.
      이러한 경우 상태 끌어올리기(Lifting State Up)으로 해결할 수 있다.

      상태 끌어올리기는 부모 컴포넌트 내에 작성된 상태를 변경시키는 함수(handler)를 자식 컴포넌트에 props로 전달해서 자식 컴포넌트 내에서 전달 받은 상태 변경 함수를 호출하도록 하는 것이다.

      이를 통해 하위 컴포넌트에서 변경된 데이터를 상위 컴포넌트로 전달할 수 있다.

      이는 데이터가 위에서 아래로 흐르는 React의 단방향 데이터 흐름의 원칙에 따라 하위 컴포넌트에서 데이터를 직접 상위로 전달하는 것과 다르게 상태(state)를 직접 전달하는 것이 아닌 <상태 갱신 함수>를 전달 받아 해당 함수를 실행함으로써 단방향 데이터 흐름을 유지할 수 있는 해결 방법이다.

  • React의 데이터 흐름에 대해 이해하고 state를 전달할 수 있다.

    o (위에서 설명)

  • 상태 끌어올리기를 활용하여, 원하는 컴포넌트에서 state를 변경할 수 있다.

    o
    동일한 데이터를 여러 컴포넌트에 반영하고 싶다면, 가장 가까운 공통 조상으로 state를 끌어올리는 것이 좋다.

  • Side Effect의 개념에 대해서 이해할 수 있다.

    o
    Side Effect는 부수 효과를 의미한다.
    부수 효과란, 함수 내에서의 어떤 구현이 함수 외부에 영향을 끼치는 경우를 의미힌다.

    주로 컴포넌트 내에서 fetch를 이용하여 API 정보를 가져오거나,
    이벤트를 활용하여 DOM을 직접 조작할 때,
    side effect가 발생했다고 말한다.

  • Effect Hook을 이용해 비동기 호출 및 AJAX 요청과 같은 side effect를 React 컴포넌트 내에서 처리할 수 있다.

    o
    Effect Hook인 useEffect는 컴포넌트 내에서 side effect를 실행할 수 있도록 하는 Hook이다.

    이 컴포넌트에서 실행하는 side effect는 브라우저 API를 이용하여 타이틀을 변경하는 것이다.

    React Hook은 최상위에서만 호출해야 한다.
    그래야 컴포넌트가 렌더링 될 때마다 항상 동일한 순서의 Hook 호출이 보장된다.
    또한, React 함수 내에서 Hook을 호출해야 한다.
    일반적이 자바스크립트 함수인 반복문 또는 조건문 내부에서
    Hook을 사용하게 되면, React가 올바르게 각 Hook의 상태를 유지할 수 없게 된다.

  • 네트워크 요청이 느릴 경우에 표시되는 로딩 화면을 구현할 수 있다.

    o
    외부 API 접속이 느릴 경우를 고려하여 사용자가 해당 페이지를 이탈하지 않고 대기할 수 있도록 빈 화면이 아닌 로딩 화면(loading indicator)의 구현을 해야한다.
    이때, 로딩화면의 구현에도 상태처리가 필요하다.

const [isLoading, setIsLoading] = useState(true);
//생략. Loading Indicator 컴포넌트를 별도로 구현했음을 가정
return {isLoading? <Loading Indicator/> : <div>로딩 완료 화면</div>}


useEffect(() => {
	setIsLoading(true);
    fetch(데이터를 요청할 서버 URL)
    	.then(resp => resp.json())
        .then(result => {
        	setProverbs(result);
            setIsLoading(false);
        });
}, [filter])
  • Side effect가 어떤 의미인지 알 수 있다.

    o (위에서 설명)

  • React 컴포넌트를 만들 때 side effect로부터 분리해서 생각할 수 있다.

    o

  • Side effect의 예를 들 수 있다.

    o
    AJAX 요청이 필요하거나, LocalStorage 또는 타이머와 같은 React와 상관없는 API를 사용하는 경우가 발생할 수 있다.
    이는 React의 입장에서는 전부 Side Effect다.
    React는 Side Effect를 다루기 위한 Hook인
    Effect Hook을 제공한다.

    따라서 React 컴포넌트에서의 Side Effect는
    타이머 사용 (setTimeout)과
    데이터 가져오기 (fetch API, localStorage)가 있다.

  • Math.sqrt()와 Math.random() 중 순수 함수는 무엇이며, 왜일까?

    Math.sqrt(x)는 인자(x)로 받은 수의 제곱근을 구하는 함수다. 따라서 늘 전달 받은 인자의 제곱근이라는 동일한 결과값을 리턴하므로 순수 함수다.
    반면, Math.random()은 동일한 입력에도 다른 출력이 나올 수 있으므로 순수 함수가 아니다. 아무런 인자를 받지 않아도 다른 출력이 나올 수 있다.

  • 어떤 함수가 fetch API를 이용해 AJAX 요청을 한다고 가정해보자.
    이 함수는 순수 함수가 아니다. 왜일까?

    순수 함수는 Side Effect를 만들지 않는 함수다.
    그러나 AJAX 요청은 외부 상태를 바꾸기 때문에 해당 기능을 가진 함수는 순수 함수가 아니다.

  • Effect Hook에서의 dependency array 사용법을 이해할 수 있다.

    o
    Effect Hook인 useEffect는 첫 번째 인자로 함수를 받고,
    두 번째 인자로 종속성 배열을 받는다.

    첫 번째 인자인 함수는 컴포넌트가 처음 생성될 때(mount될 때),
    새로운 props가 전달될 때, 상태가 바뀔 때, 컴포넌트가 종료될 때(unmount될 때) 해당 함수 내에서 side effect를 실행한다.

    두 번째 인자인 종속성 배열은 effect hook의 첫 번째 인자인 함수가 실행되는 조건을 담고 있다. 배열에 있는 각 종속성은 표현식이 아닌 어떠한 값으로 할당하며, 반드시 존재해야 하는 것은 아니다.

    배열 내의 어떤 값이 변할 때만, effect가 발생하는 첫 번째 인자의 함수가 실행된다.

    종속성 배열은 반드시 존재하지 않아도 된다.
    존재하지 않을 경우에는 첫 번째 인자인 함수만 존재하는 기본 형태이므로 업데이트 될 때마다 함수가 실행한다.

  • 컴포넌트 내에서 네트워크 요청 시, 로딩 화면과 같이 보다 나은 UI를 만드는 법을 이해할 수 있다.

    o (위에서 설명)


추가 학습

  • useEffect를 언제, 왜 사용할까?

    컴포넌트는 단방향 데이터 흐름의 원칙 때문에 props를 통해 전달 받은 데이터가 어디서 왔는지 전혀 알지 못한다.
    따라서 하위 컴포넌트는 상위 컴포넌트로부터 전달 받은 데이터의 형태 혹은 타입만 무엇인지 알 수 있다.

    이러한 특정 상태가 변하면, 재렌더링 되는데 이는 불필요한 렌더링으로 어떤 상태가 변한 건지는 알 수가 없다.

    그러나 useEffect를 사용하여 두 번째 인자인 배열에 값을 넣으면,
    그 값이 업데이트 될 때마다 useEffect 함수가 실행되어 어떤 상태가 변한건지 상태를 추적할 수 있어서 후속처리가 가능하도록 한다.


종합퀴즈

4번)

import React, { useState } from "react";

export default function ParentComponent() {
  const [value, setValue] = useState("날 바꿔줘!");

  const handleChangeValue = () => {
    setValue("보여줄게 완전히 달라진 값");
  };

  return (
    <div>
      <div>값은 {value} 입니다</div>
      <ChildComponent 1._____________ />
    </div>
  );
}

function ChildComponent(2._____________ ) {
  const handleClick = () => {
    // 이 버튼을 눌러서 부모의 상태를 바꿀 순 없을까?
		3._____________ 
  };

  return <button onClick={handleClick}>값 변경</button>;
}

단방향 데이터 흐름이라는 원칙에 따라,
부모 컴포넌트에서 자식 컴포넌트로 “상태를 변경하는 함수” 그 자체를 하위 컴포넌트에 전달하고 이 함수를 하위 컴포넌트가 실행해야 한다.

따라서 1번에는 handleChangeValue() 함수를 변수에 담아서
하위 컴포넌트에 보내줘야 하므로
✅ 1번은 handleBtnClick={handleChangeValue}

그 후 하위 컴포넌트에서는 함수를 설정한 변수명으로 받아야 하기 때문에 ✅ 2번은 {handleBtnClick} 로 받아와 줘야 한다.

마지막으로 받아온 함수를 실행하기 위해
✅ 3번은 handleBtnClick() 이 된다.

6번)

다음 중 빈 칸에 들어갈 코드로 옳은 것을 고르시오.
아래 Main 컴포넌트의 🔸첫 화면은 로딩 화면 없이🔸 항공편 리스트를 보여준다.
🔸항공편 검색 시에 로딩 상태를 보여주고🔸,
🔸검색이 완료 되면🔸 그에 맞는 항공편 리스트가 보이도록 구현한다.

import LoadingIndicator from './component/LoadingIndicator'

export default function Main() {
  1._________________ // loading useState를 만들어 주세요
	//생략, condition State와 flightList State는 구현했음을 가정합니다.

  useEffect(() => {
    2._________________ // 갱신함수를 실행시켜 주세요
		fetch(`http://서버주소/flight?q=${condition}`)
    .then(resp => resp.json())
    .then(result => {
			setFlightList(result)
      3._________________ ;
    });
  }, [condition]) 

//생략, search 컴포넌트와 flightList 컴포넌트는 구현했음을 가정합니다.
  return (
    <div>
      <main>
        <div className="table">
          4._________________ // 삼항연산자를 이용하세요
        </div>
      </main>
    </div>
  )
}

첫 화면에서는 로딩 화면 없이 항공편 리스트가 보여져야 하므로 isLoading의 초깃값이 false여야 한다.
✅ 1. const [isLoading, setIsLoading] = useState(false)

데이터를 받기 전에 isLoading을 true로 바꿔주어 항공편 검색 시에 로딩 화면(Loading indicator)을 보여준다.
✅ 2. setIsLoading(true)

데이터를 다 받으면 isLoading이 false가 되며,
로딩 완료 화면이 나오게 된다.
✅ 3. setIsLoading(false)

삼항연산자를 사용하여 작성한다.
✅ 4. {isLoading ? <LoadingIndicator /> : <div>로딩 완료 화면</div>}


과제 - StatesAirline Client part 1

주어진 StatesAirline Client 앱은 아직 미완성 상태다.

  • 앞에서 배운 '상태 끌어올리기', '데이터 흐름 개념'을 활용하여
    항공편 검색 기능을 구현한다.
  • 이번 과제의 핵심은 네트워크 요청을 통해 항공편 리스트를 받아오고,
    도착지 정보 검색 기능을 구현하는 것이다.
  • 이 기능 구현을 위해서 상태 변경 함수를 어디로 전달할지,
    Effect hook을 어떻게 활용할 수 있을지를 고민해 본다.

소감

🔡➡️💻➡️🤓👍

오늘은 오전에 학습 내용을 이해하는 데에 시간이 조금 걸렸다.
useEffect가 언제, 왜 사용하는지에 대해 이해하는 데에 시간이 걸렸기 때문이다. 이전에 잘 이해가 되지 않았던 fetch API도 다시 이해하느라 시간이 걸렸다.

그렇지만, 재밌는 부분이었다.
종합퀴즈를 풀고 애매했던 부분과 틀린 부분을 다시 한 번 보면서
좀 더 확실하게 이해할 수 있었다.

내일 오전에는 Part2 과제를 진행하고,
오후에 section 1을 복습할 예정이다.

profile
developerpyk

0개의 댓글