SatesAirline 회고

arrrrrr·2023년 2월 5일

React 공부중 🎽

목록 보기
3/16

Summary

요구 사항

  • 네트워크 요청으로 항공편 리스트 받아오기
  • 네트워크 요청이 느릴 경우 로딩 화면 노출하기

학습 내용

  • state, props는 항상 객체 형태로 전달된다.
  • 데이터 흐름을 고려하여 state 관리하기
  • 컴포넌트 구조 이해하기
  • 상태 끌어올리기
  • 불필요한 렌더링을 막기위한 useEffect hook
  • 렌더링 최적화를 위한 batching

파일 구조

  • api
    * FlightDataApi.js # 항공편 정보를 받아오는 API
  • pages
    * Main.js # 첫 화면 컴포넌트, 필터링 상태 관리
    • component
      * Flight.js # 단일 항공편
      • FlightList.js # 항공편 목록
        • LoadingIndicator.js # 로딩 컴포넌트
        • Search.js # 검색 컴포넌트, 필터링 상태 변경

Code

  • RESTful api
    REST api 작성이 과제였으나 응답은 restful하게 오지 않아 어떻게 작성해야할지 고민이었다.
    고민이 무색하게 REST api는 3단계 기준까지 엄격하게 지켜야하나, 아래 코드는 클라이언트 측에서 작성할 수 있는 모든 기준을 충족했기 때문에 Restful하다고 말할 수 있다고 한다.
  • 필터링
    데이터를 외부에서 필터링하는 방법을 선택했다. 유저로부터 선택된 항공편을 props로 내려받아 query string을 만들었다.
    항공편이 선택되지 않아 undefined 값이 내려오는 오류를 방지하기 위해 default vaule를 빈 객체로 주었다.
export async function getFlight(filterBy = {}) {
  let url = 'http://ec2-13-124-90-231.ap-northeast-2.compute.amazonaws.com:81/flight?'

  if (filterBy.departure) url += `departure=${filterBy.departure}`
  if (filterBy.destination) url += `&destination=${filterBy.destination}`
  const response = fetch(url).then((res) => res.json())

  return response;
}
  • useEffect
    리액트의 편리한 점은 업데이트된 정보가 있으면 자동으로 리렌더링을 한다는 것이다.
    하지만 이는 날씨 api와 같이 여러번 렌더할 필요가 없는 코드에는 비효율적이다.
    불필요한 렌더링을 방지하기 위해, 언제 코드를 실행할지 선택하는 방법으로 useEffect hook을 사용할 수 있다.
    useEffect(한번만 실행할 함수 코드, [지켜볼 state])
    렌더링 시점은 컴포넌트가 렌더링 된 후이다.
 useEffect(() => {
    setLoading(true);
    getFlight(condition).then((res) => {
      setFlightList(res);
      setTimeout(() => { //로딩화면을 보기 위해 임의로 비동기 처리를 했다. 
        setLoading(false);
      }, 300);
    });
  }, [condition])
  • 로딩 화면
  • 상태 끌어올리기

유저의 항공편 검색 결과는 Main.js파일의 condition state가 가지고 있다.

export default function Main() {
  // 항공편 검색 조건을 담고 있는 상태
  const [condition, setCondition] = useState({});
...}

condition state는 search 함수가 실행되면 변경되는데, search 함수는 Search 컴포넌트에 props로 보내어 해당 컴포넌트에서 실행된다.

// Main.js
const search = ({ departure, destination }) => {
    if (
      condition.departure !== departure || 
      condition.destination !== destination 
    ); {
      setCondition({ departure, destination });
    };
  };

// <Search />
// 상태함수를 props로 받음
function Search({ onSearch }) {
  const [textDeparture, setTextDeparture] = useState('');
  const [textDestination, setTextDestination] = useState('');

  const handleSearchClick = () => {
    onSearch({ departure: textDeparture, destination: textDestination })};
...}

0개의 댓글