React 및 2개의 API를 사용하여 국가 브라우저 구축

17876 단어 reactwebdevtutorial
현장 프레젠테이션: https://country-browser-azure.vercel.app/
환매 여기 있습니다: https://github.com/afgonullu/country-browser
React, React Bootstrap, 2개의 API, REST Countries API, Weatherstack API를 사용하여 국가 브라우저 프로그램을 구축할 것입니다.

프로젝트 작성


제공된 템플릿을 사용하여 새 React 프로젝트를 작성합니다.npx create-react-app country-browser모든 작업이 끝난 후 npm start을 실행하면 React 프로그램이 실행 중입니다. 페이지 중앙에 회전하는 React 로고가 있습니다.
몇 개의 서류가 있어서 우리는 사용할 수 없다.너는 원형을 유지할 수도 있고 삭제할 수도 있다.명확하고 깔끔한 구조를 원하는 경우 다음 파일을 삭제합니다.
country-browser
└── src
    ├── App.css
    ├── App.test.js
    ├── logo.svg
    ├── reportWebVitals.js
    └── setupTests.js
이 파일들을 삭제했기 때문에, 프로그램이 정상적으로 작동하지 않을 것입니다.우리는 index.jsapp.js의 일부 물건을 조정하고 정리해야 한다
import React from "react"
import ReactDOM from "react-dom"
import "./index.css"
import App from "./App"

ReactDOM.render(<App />, document.getElementById("root"))
const App = (props) => {
  return <h1>Hello World. Welcome to Country Browser</h1>
}

export default App
package.json의 프로젝트 의존항도 정리해야 한다.이렇게 해야 합니다.
///
...
"dependencies": {
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-scripts": "4.0.1"
  },
...
///
현재, 만약 우리가 다시 npm start을 사용하여 실행한다면, 우리는 브라우저에서 우리의 신기한 문자를 볼 수 있을 것이다.이것은 우리 프로젝트의 출발점이다.

설계


완전한 프로젝트에서, 너는 완전한 설계 시스템이 필요하다.예를 들어, Concept는 다음과 같은 템플릿을 제공합니다.

이 항목에 대해 우리는 레이아웃과 색깔을 결정할 것이다.
포석에 대해 우리는 이렇게 말할 수 있다.
  • 우리는 왼쪽 사이드바를 사용하여 모든 국가를 열거할 것이다.
  • 사이드바의 검색 기능도 제공되므로 사용자가 국가
  • 을 필터링할 수 있습니다.
  • 은 국가를 선택할 때 선택한 국가에 따라 주요 부분을 채운다.
  • 색깔에 관해서는우리 정자에 갑시다.첫 번째 무작위 색 배열 공동 선택:

    흰색을 배경색으로 하고, 다른 색은 주제색으로 하겠습니다.Webaim Contrast Checker Tool을 사용하여 색상의 명암비를 확인할 수 있습니다.이렇게 하면, 우리는 우리의 색깔이 배경에서 보기에 쉽게 이해되고 읽을 수 있도록 확보할 것이다.

    레이아웃 및 주제 구현


    Bootstrap은 좋은 도구입니다. React Bootstrap library는 UI 기반을 만드는 좋은 도구입니다.먼저 설치하겠습니다.
    npm install react-bootstrap bootstrap
    
    bootstrap도 설치할 것입니다. 왜냐하면 bootstrap 테마에 대해 간단한 맞춤형 제작을 원하기 때문입니다.또한 Sass 파일을 컴파일하기 위한 need to install node-sass도 있습니다.
    npm install --save [email protected]
    
    (Node Sass가 v5로 업데이트되었으며 create react app package에서 v5를 지원하지 않습니다. 따라서 설치 시 버전 선언이 중요합니다.
    그 후에 모든 것이 정상적인지 확인하기 위해 App.js 파일을 약간 수정했습니다.
    import "./App.scss" // custom theme for bootstrap
    import { Container, Row, Col } from "react-bootstrap" // React bootstrap components
    
    const App = (props) => {
      return (
        <Container fluid>
          <Row>
            <Col md="3">Sidebar</Col>
            <Col md="9">Main Section</Col>
          </Row>
        </Container>
      )
    }
    
    export default App
    
    Dell의 App.scss 파일은 다음과 같습니다.
    @import "~bootstrap/scss/bootstrap";
    
    한 줄만 있습니다. 안내를 가져옵니다.scss 파일.우리가 위에 무엇을 썼든지 간에, 그것은 맞춤형 바닐라 가이드를 만들 것이다.이렇게 하면, 우리는 적당한 맞춤형 파일과 원본 파일을 깨끗하게 유지할 것이다.
    테마 색상을 정확하게 정의합니다.이를 위해 부트 주제 색상 정의만 덮어씁니다./node_modules/bootstrap/scss/_variables.scss에서 찾을 수 있습니다.App.scss의 최종 버전은 다음과 같습니다.
    $theme-white: #ffffff;
    $cerulean-crayola: #00a7e1;
    $rich-black: #00171f;
    $prussian-blue: #003459;
    $cg-blue: #007ea7;
    
    $theme-colors: (
      "primary": $prussian-blue,
      "secondary": $cg-blue,
      "info": $cerulean-crayola,
      "light": $theme-white,
      "dark": $rich-black,
    );
    
    @import "~bootstrap/scss/bootstrap";
    

    첫 번째 API 호출

    axios을 설치하겠습니다.
    npm install axios
    

    Right now, I will not go over REST APIs, HTTP methods, axios or React Hooks. I would write specific blog posts about them in the future and link them here.If you feel that you need to understand them better, please do it now before proceeding.


    우리는 https://restcountries.eu/rest/v2/all단점을 사용할 것이다.만약 우리가 링크를 복사하여 브라우저에 붙인다면, 우리는 응답과 대상 그룹으로 돌아가는 각종 정보를 볼 수 있을 것이다.우리가 데이터를 필터하거나 처리해야 할 때, 이 점은 매우 중요하다.
    API를 호출하여 데이터를 가져오고 응답을 콘솔에 기록할지 확인합니다.
    ...
      useEffect(() => {
        const fetchData = async () => {
          const response = await axios.get("https://restcountries.eu/rest/v2/all")
    
          console.log(response.data)
          setCountries(response.data)
        }
    
        fetchData()
      }, [])
    ...
    
    만약 우리가 브라우저에서 컨트롤러를 열면 250개의 대상의 그룹을 볼 수 있을 것이다.
    됐어, 진지해질 때가 됐어.우선, 우리는 상태 변수를 만들어야 한다.
    const [countries, setCountries] = useState([])
    
    만약useState 갈고리에 익숙하지 않다면, 나는 다시 한 번 당신에게 그것을 이해하라고 건의합니다.한 마디로 하면useState는 기능 구성 요소의 상태를 더욱 유연하게 관리할 수 있습니다.
    API 호출이 반환되는 배열을 저장하려면 countries 변수를 사용합니다.우리는 응용 프로그램이 나타날 때 전화를 걸 것이다.국가는 영원히 변하지 않기 때문에, 매번 구성 요소가 나타날 때마다 호출되는 것을 피하기 위해서,useEffect 갈고리를 약간 수정했습니다.
    마지막 단계는 페이지에 데이터를 표시하는 것입니다.map 함수와 기타 수조 함수는 동적 데이터를 처리할 때 관건적인 도구이다.우리는 countries 변수를 통해 간단하게 사이드바에 국가의 이름을 표시할 수 있다.
    이때 App.js은 다음과 같습니다.
    import React, { useEffect, useState } from "react"
    import axios from "axios"
    import "./App.scss"
    import { Container, Row, Col, ListGroup, ListGroupItem } from "react-bootstrap"
    
    const App = (props) => {
      const [countries, setCountries] = useState([])
      useEffect(() => {
        const fetchData = async () => {
          const response = await axios.get("https://restcountries.eu/rest/v2/all")
    
          setCountries(response.data)
        }
    
        fetchData()
      }, [countries])
    
      return (
        <Container fluid>
          <Row>
            <Col md="3">
              <ListGroup>
                {countries.map((country) => (
                  <ListGroupItem key={country.name}>{country.name}</ListGroupItem>
                ))}
              </ListGroup>
            </Col>
            <Col md="9">Main Section</Col>
          </Row>
        </Container>
      )
    }
    
    export default App
    
    

    검색 및 필터링


    다음 단계에서는 검색 및 필터링 기능을 추가합니다.그것은 코드 구조에 대해 약간의 추가와 변경을 해야 한다.
    우선, 우리는 현재 countries의 지도를 그리고 있다.기능적인 사이드바를 만들기 위해서는 검색 값의 결과를 나타내는 동적 상태가 필요합니다.둘째, 일부 UI 요소와 검색 논리를 구현해야 합니다.그래서 우리가 필요로 하는 것은,
  • UI 요소, 즉 검색 양식
  • 검색 및 필터 논리
  • 스토리지 검색 조건의 상태 변수
  • 필터링된 국가용
  • 상태 변수
    React 부트 라이브러리의 양식 컨트롤 요소처럼 간단합니다.우리는 onChange을 사용합니다. 왜냐하면 우리는 매번 키를 눌렀을 때 필터를 하는 논리를 실현할 것입니다.
    ...
    <Form>
      <Form.Control
        value={search}
        type="text"
        placeholder="Filter Countries..."
        onChange={handleSearch}
      />
    </Form>
    ...
    
    상태 변수는 다음과 같습니다.
      const [filtered, setFiltered] = useState([])
      const [search, setSearch] = useState("")
    
    논리는 상당히 간단하다.handleSearch은 매번 버튼을 눌렀을 때 상태 변수 search을 설정합니다.search이 변경되었기 때문에, 부품은 다시 입찰되고, 우리의 useEffect은 다시 집행될 것입니다.실행할 때, search 변수에 저장된 문자열에 따라 필터를 합니다.
      useEffect(() => {
        setFiltered(
          countries.filter((country) =>
            country.name.toUpperCase().includes(search.toUpperCase())
          )
        )
      }, [countries, search])
    
      const handleSearch = (event) => {
        setSearch(event.target.value)
      }
    
    현재, 이 프로그램을 실행하면, 검색 기능이 예상대로 실행되는 것을 볼 수 있습니다.우리의 App.js은 이 단계에서 보면 다음과 같다.
    import React, { useEffect, useState } from "react"
    import axios from "axios"
    import "./App.scss"
    import {
      Container,
      Row,
      Col,
      ListGroup,
      ListGroupItem,
      Form,
    } from "react-bootstrap"
    
    const App = (props) => {
      const [countries, setCountries] = useState([])
      const [filtered, setFiltered] = useState([])
      const [search, setSearch] = useState("")
    
      useEffect(() => {
        const fetchData = async () => {
          const response = await axios.get("https://restcountries.eu/rest/v2/all")
    
          setCountries(response.data)
        }
    
        fetchData()
      }, [countries])
    
      useEffect(() => {
        setFiltered(
          countries.filter((country) =>
            country.name.toUpperCase().includes(search.toUpperCase())
          )
        )
      }, [countries, search])
    
      const handleSearch = (event) => {
        setSearch(event.target.value)
      }
    
      return (
        <Container fluid>
          <Row>
            <Col md="3">
              <Form>
                <Form.Control
                  value={search}
                  type="text"
                  placeholder="Filter Countries..."
                  onChange={handleSearch}
                />
              </Form>
              <ListGroup>
                {filtered.map((country) => (
                  <ListGroupItem key={country.name}>{country.name}</ListGroupItem>
                ))}
              </ListGroup>
            </Col>
            <Col md="9">Main Section</Col>
          </Row>
        </Container>
      )
    }
    
    export default App
    

    국가 세부 정보 표시


    사용자가 어느 나라를 눌렀을 때, 우리는 국가의 상세한 정보를 보여 주고 싶습니다.이를 실현하기 위해서는 우선 onClick마다 ListGroupItem 이벤트 처리 프로그램을 추가해야 한다.
    <ListGroupItem key={country.name} onClick={() => setDetails(country)}>
      {country.name}
    </ListGroupItem>
    
    우리는 또 다른 상태 변수가 필요하다. 여기서 우리는 주요 부분의 내용을 보존할 수 있다.국가/지역을 클릭하지 않으면 주요 섹션이 비어 있어야 합니다.국가 중 하나를 클릭하면 해당 국가에 관련 정보를 표시해야 합니다.
    import React, { useEffect, useState } from "react"
    import axios from "axios"
    import "./App.scss"
    import {
      Container,
      Row,
      Col,
      ListGroup,
      ListGroupItem,
      Form,
    } from "react-bootstrap"
    
    const App = (props) => {
      const [countries, setCountries] = useState([])
      const [filtered, setFiltered] = useState([])
      const [search, setSearch] = useState("")
      const [details, setDetails] = useState([])
    
      useEffect(() => {
        const fetchData = async () => {
          const response = await axios.get("https://restcountries.eu/rest/v2/all")
    
          setCountries(response.data)
        }
    
        fetchData()
      }, [countries])
    
      useEffect(() => {
        setFiltered(
          countries.filter((country) =>
            country.name.toUpperCase().includes(search.toUpperCase())
          )
        )
      }, [countries, search])
    
      const handleSearch = (event) => {
        setSearch(event.target.value)
      }
    
      return (
        <Container fluid>
          <Row>
            <Col md="3">
              <Form>
                <Form.Control
                  value={search}
                  type="text"
                  placeholder="Filter Countries..."
                  onChange={handleSearch}
                />
              </Form>
              <ListGroup>
                {filtered.map((country) => (
                  <ListGroupItem
                    key={country.name}
                    onClick={() => setDetails(country)}
                  >
                    {country.name}
                  </ListGroupItem>
                ))}
              </ListGroup>
            </Col>
            <Col md="9">
              {details.length === 0 ? (
                ""
              ) : (
                <Container>
                  <Row className="justify-content-md-start align-items-start">
                    <Col>
                      <h1>{details.name}</h1>
                      <p>Capital City: {details.capital}</p>
                      <p>Population: {details.population}</p>
                      <h3>Languages</h3>
                      <ul>
                        {details.languages.map((language) => (
                          <li key={language.name}>{language.name}</li>
                        ))}
                      </ul>
                    </Col>
                    <Col>
                      <img
                        src={details.flag}
                        height="auto"
                        width="320px"
                        alt="country flag"
                      />
                    </Col>
                  </Row>
                </Container>
              )}
            </Col>
          </Row>
        </Container>
      )
    }
    
    export default App
    

    날씨 디테일 추가


    수도의 날씨 세부 사항을 보여주기 위해 두 번째 API를 실현합시다.Weatherstack API를 사용합니다.그것을 사용하기 위해서 우리는 계좌가 하나 필요하다.로그인할 때 대시보드에 API 액세스 키가 있습니다.이게 필요해.

    루트 폴더에 .env 파일을 만듭니다.이 파일에 key=value 쌍을 생성합니다.따옴표나 더블 따옴표를 포함한 다른 문장부호는 없어야 한다.
    또 키는 REACT_APP_으로 시작해야 한다.예를 들어, 내 .env 항목은 다음과 같습니다.
    REACT_APP_WEATHERSTACK_API_KEY=14218xxx555xxxxx78yyy26d
    
    우리는 예전처럼 두 번째 API를 만들 수 없다.처음으로, 우리는 응용 프로그램이 시작될 때 국가 데이터를 얻는다.그것은 동적이지 않고 사용자의 상호작용도 없다.다른 한편, 사용자가 국가를 선택한 후 날씨 데이터를 얻으려면 사용자의 요구에 따라 상태를 설정하고 UI를 정확하게 보여야 한다.사용자가 입력할 때마다 변경됩니다.그래서 우리는 우리의 방법을 바꿔야 한다.
    우리는 사용자가 클릭할 때 우리가 하는 일을 확장하고 하나의 단독 방법으로 -> handleSelectCountry에서 모든 일을 처리할 것이다
    const handleSelectCountry = async (country) => {
        const response = await axios.get(
          `http://api.weatherstack.com/current?access_key=${process.env.REACT_APP_WEATHERSTACK_API_KEY}&query=${country.capital}`
        )
    
        const weather = response.data.current
    
        setDetails(
          <Container>
            <Row className="justify-content-md-start align-items-start">
              <Col>
                <h1>{country.name}</h1>
                <p>Capital City: {country.capital}</p>
                <p>Population: {country.population}</p>
                <h3>Languages</h3>
                <ul>
                  {country.languages.map((language) => (
                    <li key={language.name}>{language.name}</li>
                  ))}
                </ul>
                <h3>Weather in {country.capital}</h3>
                <p>temperature: {weather.temperature} Celcius</p>
                <img src={weather.weather_icons[0]} alt="Temp Icon" />
                <p>Wind Speed: {weather.wind_speed} mph</p>
                <p>Wind Direction: {weather.wind_dir}</p>
              </Col>
              <Col>
                <img
                  src={country.flag}
                  height="auto"
                  width="320px"
                  alt="country flag"
                />
              </Col>
            </Row>
          </Container>
        )
      }
    
    이전에 우리는 주 세부 정보를 이용하여 국가 데이터를 저장했다.현재, 우리는 출력된 JSX 코드를 저장합니다.JSX를 구성하기 전에 날씨 API를 비동기적으로 호출했습니다.
    결과는 다음과 같습니다.

    비록 여전히 약간의 미화와 맞춤형 제작이 필요하지만, 우리의 프로젝트는 이미 완성되었다.나는 아래에서 나의 결과를 공유할 것이다.너는 스스로 이 부분을 시험해 볼 수 있다.
    이 프로젝트의 현장 프레젠테이션은 https://country-browser-azure.vercel.app/에서 제공됩니다.
    저장소 위치: https://github.com/afgonullu/country-browser

    I would love to hear your opinions and continue conversation. If you want to get in touch, feel free to follow me and send me a message on twitter

    좋은 웹페이지 즐겨찾기