티스토리 뷰

React

상태끌어올리기 2 : statesairline-client

이채야채 2021. 12. 4. 13:34

상태끌어올리기에 대해서 공부했으니 실제 코드를 보면서 자세히 공부해보자.

페어와 함께 했던것을 다시보면 이해를 못했던것이 반이상이기에 혼자서 꼭 다시풀어보는 시간이 필요하다. (2~3일 후 까먹을쯤ㅋㅋ)

 

 

 

처음 받았던 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 상태를 변경시킵니다')
    
      // 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/>
        <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>
  )
}

1. search 함수에서 condition을 업뎃해야한다. setCondtion 이라는 변경함수로 변수 condtion을 변경시킨다.

파라미터로 들어오는값을 보니 {departure, destination} 두개가 들어온다. useState를 보니, 초기값으로는 departure 값만 있다. 

 --> {departure, destination} 이렇게 넣어줘도되나? {departure : '인천' , destination : '부산'} 이렇게 해아하나? 고민이들어 콘솔을 찍어봤다. 객체에서는 변수에 값이 할당되고 그게 키로들어오면 저절로 value에 값이 들어간다. 

 

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 상태를 변경시킵니다')
        // TODO:
      setCondition({departure , destination})
    
    
    }
  }

  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}/>
        <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>
  )
}

 

자꾸 왜 기본적인곳에서 무너지냐 ㅠㅠ. 기본 다시 잡고가자.

 

2. 상태를 어디로 내려줘야하나? onSearch라는 이름으로 내려줘야하는구나

 

Search컴포넌트를 봐보자.

 

import { useState } from 'react'

function Search() {
  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 함수가 실행됩니다')
  

    // 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

온체인지 => 핸들체인지 함수로인하여 setTextdestination 이라는 변경함수 -> textdestination이라는 변수가 바뀌고 value = {textDestination}이니 그값이 밸류가된다. onkeypress부분을보면 핸들키프레스에 조건이 맞으면 handlesearchclick함수가실행.

 

결국 Handlesearchclick에서 서치함수를 실행해야한다.내려준 Onsearch에 값을넣어서 실행시키면

Seach컴포넌트에 구체적인 값이 Onsearch 함수에서 실행이되면 타고타고 올라와서(상태끌어올리기) setCondition {departure:destination} 에 도달하여 메인부분(부모컴포넌트)에 값이 바뀐다. 

 

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

    // 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

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG more
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함