2020.코딩일지

React실습 - im-sprint-statesairline-client 본문

JS & React

React실습 - im-sprint-statesairline-client

개발하는라푼젤 2022. 8. 2. 05:18
728x90

🛫StatesAirlline Client

 

part1.에서는 파일2개만 수정하면 된다.

  • useState의 condition 업데이트하기
  • 자식이 부모에게 props전달하기
Main.js
더보기
import Head from 'next/head'
import { useEffect, useState } from 'react'
import { getFlight } from '../api/FlightDataApi'
import FlightList from './component/FlightList'
import LoadingIndicator from './component/LoadingIndicator'
import Search from './component/Search'
import Debug from './component/Debug'

import json from '../resource/flightList'

export default function Main() {
  const [condition, setCondition] = useState({
    departure: 'ICN'
  })
  const [flightList, setFlightList] = useState(json)

  const search = ({ departure, destination }) => {
    if (condition.departure !== departure || condition.destination !== destination) {
      console.log('condition 상태를 변경시킵니다')
      setCondition({departure:departure, destination:destination}) //🧐
      // TODO:
    }
  }

  const filterByCondition = (flight) => {
    let pass = true;
    if (condition.departure) {
      pass = pass && flight.departure === condition.departure
    }
    if (condition.destination) {
      pass = pass && flight.destination === condition.destination
    }
    return pass;
  }

  global.search = search // 실행에는 전혀 지장이 없지만, 테스트를 위해 필요한 코드입니다. 이 코드는 지우지 마세요!

  return (
    <div>
      <Head>
        <title>States Airline</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main>
        <h1>
          여행가고 싶을 땐, States Airline
        </h1>
        <Search onSearch={search} /> 
        {/* 🧐 여기에서 컴포넌트에 함수넣어주고 Search컴포넌트가서 */}
        <div className="table">
          <div className="row-header">
            <div className="col">출발</div>
            <div className="col">도착</div>
            <div className="col">출발 시각</div>
            <div className="col">도착 시각</div>
            <div className="col"></div>
          </div>
          <FlightList list={flightList.filter(filterByCondition)} />
        </div>

        <div className="debug-area">
          <Debug condition={condition} />
        </div>
      </main>
    </div>
  )
}

 

 

component/Search.js
더보기
import { useState } from 'react'

function Search({onSearch}) { //🧐부모로보낼 함수받아주고
  const [textDestination, setTextDestination] = useState('')

  const handleChange = (e) => {
    setTextDestination(e.target.value.toUpperCase())
  }

  const handleKeyPress = (e) => {
    if (e.type === 'keypress' && e.code === 'Enter') {
      handleSearchClick()
    }
  }

  const handleSearchClick = () => {
    console.log('검색 버튼을 누르거나, 엔터를 치면 search 함수가 실행됩니다')
    onSearch( {departure:"ICN", destination : textDestination}); //🧐 search에넘길 파라미터 맞춰서기입
    // TODO:
  }

  return <fieldset>
    <legend>공항 코드를 입력하고, 검색하세요</legend>
    <span>출발지</span>
    <input id="input-departure" type="text" disabled value="ICN"></input>
    <span>도착지</span>
    <input id="input-destination" type="text" value={textDestination} onChange={handleChange} placeholder="CJU, BKK, PUS 중 하나를 입력하세요" onKeyPress={handleKeyPress} />
    <button id="search-btn" onClick={handleSearchClick}>검색</button>
  </fieldset>
}

export default Search

 


 

 

part2.

`filterByCondition`를 사용하지않았는데도 왜 패스안됨?  주석처리도안되고 완전삭제해야함
FlightDataApi.js에서 fetch도 했는데??  만약 출착정보가 잘못들어왔거나 없다면,  `~flight?` 이후 아예 없어야하기때문에 ...

임베드해주는게맞는것같음.

import flightList from '../resource/flightList'
import fetch from 'node-fetch'

if (typeof window !== "undefined") {
  localStorage.setItem('flight', JSON.stringify(flightList));
}

export function getFlight(filterBy = {}) {
  // HINT: 가장 마지막 테스트를 통과하기 위해, fetch를 이용합니다. 아래 구현은 완전히 삭제되어도 상관없습니다.
  // TODO: 아래 구현을 REST API 호출로 대체하세요.
  const dep = filterBy.departure
  const des = filterBy.destination
//❌이렇게하면 안된다
  const url = `http://ec2-13-124-90-231.ap-northeast-2.compute.amazonaws.com:81/flight?$departure=${dep}&destination=${des}`
  console.log(url);
//❌출착정보가 들어오면 문제없는 fetch일테지만, 출착정보중 하나라도 안들어오거나 잘못들어온다면? 아예 '~flight?'뒤에도 안나와야한다.
  
  
  return  fetch(url).then((res)=>res.json())
  }
export function getFlight(filterBy = {}) {
  // HINT: 가장 마지막 테스트를 통과하기 위해, fetch를 이용합니다. 아래 구현은 완전히 삭제되어도 상관없습니다.
  // TODO: 아래 구현을 REST API 호출로 대체하세요.
  let emString = "";
  if (filterBy.departure) {
    emString = emString + `departure=${filterBy.departure}&`;
  }
  if (filterBy.destination) {
    emString = emString + `destination=${filterBy.destination}`;
  }
  let endpoint = `http://ec2-13-124-90-231.ap-northeast-2.compute.amazonaws.com:81/flight?${emString}`;

  return fetch(endpoint).then((res) => res.json());
}

 

im-sprint-statesairline-client/pages/main.js의 useEffect부분

 

 

im-sprint-statesairline-client/pages/main.js

더보기
im-sprint-statesairline-client/pages/main.js
import Head from "next/head";
import { useEffect, useState } from "react";
import { getFlight } from "../api/FlightDataApi";
import FlightList from "./component/FlightList";
import LoadingIndicator from "./component/LoadingIndicator";
import Search from "./component/Search";
import Debug from "./component/Debug";

import json from "../resource/flightList";

export default function Main() {
  const [isLoading, setIsLoading] = useState(false);
  const [condition, setCondition] = useState({
    departure: "ICN",
  });
  const [flightList, setFlightList] = useState(json);

  const search = ({ departure, destination }) => {
    //구조분해로 받음
    if (
      condition.departure !== departure ||
      condition.destination !== destination
    ) {
      console.log("condition 상태를 변경시킵니다");
      //setCondition({departure:departure, destination:destination}) //🧐
      setCondition({ departure, destination }); //1️⃣ 키=값 같으면 한번만적어도됨
      // TODO:
    }
  };

  useEffect(async () => {
    setIsLoading(true);
    setFlightList(await getFlight(condition)); //필터링 조건인 객체를 인자로 넣어준다.
    setIsLoading(false);
  }, [condition]);

  global.search = search; // 실행에는 전혀 지장이 없지만, 테스트를 위해 필요한 코드입니다. 이 코드는 지우지 마세요!

  return (
    <div>
      <Head>
        <title>States Airline</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main>
        <h1>여행가고 싶을 땐, States Airline</h1>
        <Search onSearch={search} />
        {/* 🧐 여기에서 컴포넌트에 함수넣어주고 Search컴포넌트가서 */}
        <div className="table">
          <div className="row-header">
            <div className="col">출발</div>
            <div className="col">도착</div>
            <div className="col">출발 시각</div>
            <div className="col">도착 시각</div>
            <div className="col"></div>
          </div>
          {/* <FlightList list={flightList.filter(filterByCondition)} /> */}
          {/* // getFlight 요청이 다소 느리므로, 
          // 로딩 상태에 따라 LoadingIndicator 컴포넌트를 표시해야 합니다 
          // 컴포넌트 내 필터 함수 `filterByCondition` 대신 삼항연산자 사용  */}
          {isLoading ? <LoadingIndicator /> : <FlightList list={flightList} />}
        </div>

        <div className="debug-area">
          <Debug condition={condition} />
        </div>
      </main>
    </div>
  );
}

 

 

 

im-sprint-statesairline-client/pages/component/Search.js

더보기

im-sprint-statesairline-client/pages/component/Search.js

import { useState } from "react";

function Search({ onSearch }) {  //🧐부모로보낼 함수받아주고
  //구조분해로 가져옴
  const [textDestination, setTextDestination] = useState("");

  const handleChange = (e) => {
    setTextDestination(e.target.value.toUpperCase());
  };

  const handleKeyPress = (e) => {
    if (e.type === "keypress" && e.code === "Enter") {
      handleSearchClick();
    }
  };

  const handleSearchClick = () => {
    console.log("검색 버튼을 누르거나, 엔터를 치면 search 함수가 실행됩니다");
    onSearch({ departure: "ICN", destination: textDestination }); 
    //🙃검색버튼클릭시 작동되게 (도착지입력시, 저장되어있는곳textDestination이기때문에 가져옴) 
    //🙃 - 구조분해이기때문에 이렇게 적어준것임. 아니면 값만 적어도됨
    // TODO: 
  };

  return (
    <fieldset>
      <legend>공항 코드를 입력하고, 검색하세요</legend>
      <span>출발지</span>
      <input id="input-departure" type="text" disabled value="ICN"></input>
      <span>도착지</span>
      <input
        id="input-destination"
        type="text"
        value={textDestination}
        onChange={handleChange}
        placeholder="CJU, BKK, PUS 중 하나를 입력하세요"
        onKeyPress={handleKeyPress}
      />
      <button id="search-btn" onClick={handleSearchClick}>
        검색
      </button>
    </fieldset>
  );
}

export default Search;

 

 

im-sprint-statesairline-client/api/FlightDataApi.js

더보기

im-sprint-statesairline-client/api/FlightDataApi.js

import flightList from "../resource/flightList";
import fetch from "node-fetch";

if (typeof window !== "undefined") {
  localStorage.setItem("flight", JSON.stringify(flightList));
}

export function getFlight(filterBy = {}) {
  // HINT: 가장 마지막 테스트를 통과하기 위해, fetch를 이용합니다. 아래 구현은 완전히 삭제되어도 상관없습니다.
  // TODO: 아래 구현을 REST API 호출로 대체하세요.
  let emString = "";
  if (filterBy.departure) {
    emString = emString + `departure=${filterBy.departure}&`;
  }
  if (filterBy.destination) {
    emString = emString + `destination=${filterBy.destination}`;
  }
  let endpoint = `http://ec2-13-124-90-231.ap-northeast-2.compute.amazonaws.com:81/flight?${emString}`;

  return fetch(endpoint).then((res) => res.json());
}

Comments