React 실습 - StatesAirline Client

김도영·2022년 5월 24일
0
post-thumbnail
post-custom-banner

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'
import { setLazyProp } from 'next/dist/next-server/server/api-utils'

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, destination})
    }
  }

  const [isLoading, setIsLoding] = useState(true)
  
  // react 밖에 존재하는 FlightDataAPi서버를 받아야 하니 SideEffect인 useEffect를 사용
  useEffect(() => {
    setIsLoding(true) // list를 받아오기전까지 로딩
    getFlight(condition) // FlightDataApi 서버에서 데이터를 받아옴, 필터가 되고 난 후 json파싱된 값을 받음
    .then(res => {
      setFlightList(res) // setFlightList에 넣어서 flightList를 바꿔줌
      setIsLoding(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}/> 
        <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>
          {isLoading ? <LoadingIndicator /> : <FlightList list={flightList} />}
          // getFlight 요청이 다소 시간이 소요되므로
         // 로딩 상태에 따라 LoadingIndicator 를 실행
        </div>
        <div className="debug-area">
          <Debug condition={condition} />
        </div>
      </main>
    </div>
  )
}

Search.js

import { useState } from 'react'

function Search({onSearch}) { // onSearch props 받기
  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})
  }

  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

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 = {}) {
	
  // fetch로 AJAX 요청
  // 필터된 departure, destination 조건
  let feflight = ''
  if (filterBy.departure) {
    feflight = feflight + `departure=${filterBy.departure}`
  }
  
  if (filterBy.destination) {
    feflight = feflight + `&destination=${filterBy.destination}`
  }

  let endpoint = `http://ec2-13-124-90-231.ap-northeast-2.compute.amazonaws.com:81/flight?${feflight}`
  
  // 해당 주소에서 데이터를 받아 json화 시키고 리턴
  return fetch(endpoint)
  .then( res => res.json() );
  
}
profile
Blockchain Developer
post-custom-banner

0개의 댓글