React를 사용하여 날씨 응용 프로그램 만들기


소스 코드


Here

소개하다.


본문에서 우리는 사용을 배울 것이다
  • React function component
  • React hooks
  • React data management context api
  • 선결 조건

  • Visual Studio 코드(VS 코드) here에서 설치
  • 부터here 설치 노드
  • 날씨apihere를 위한 계정 만들기
  • 프로젝트 만들기


    날씨 응용 프로그램 프로젝트 만들기
    npx create-react-app weather-app
    
    위 명령은 weather-app라는 새 React 프로젝트를 만듭니다.
    디렉토리를 새 항목으로 변경
    cd weather-app
    
    명령을 사용하여 프로젝트를 성공적으로 만들 수 있도록 프로그램을 실행합시다
    npm start
    

    종속성 설치


    나는 항목에 사용되는 모든 아이콘을 표시하기 위해 깃털 아이콘을 사용한다.모든 아이콘을 찾을 수 있음here
    깃털 아이콘을react prject에 추가하려면 아래 명령을 사용하십시오
    npm i react-feather
    
    react feather 아이콘의 사용법 보이기 here

    VS 코드에서 항목 열기


    VS 코드에서 항목 열기
    code .
    

    CSS 스타일 업데이트


    이것은 간단한 항목이기 때문에, 나는 모든 스타일 코드를 파일 프로그램에 두었다.css.
    응용 프로그램의 모든 내용을 바꿉니다.내용

    응용 프로그램.css 감속기 생성

    reducers 디렉토리에 새 폴더src를 만듭니다.
    그리고 index.js 폴더 아래에 새로 만들기reducers.
    다음 코드를 index.js 파일에 복사합니다
    export const getWeather = async (api) => {
        const response = await fetch(api);
        if (!response.ok) {
            // throw an error if response has not successed
          throw new Error(`${response.status}, ${response.statusText}`);
        } else {
            return await response.json();
        }
    }
    
    export const updateWeather = (dispatch, data) => {
        let weather = {};
        weather.temprature = {
            unit: "celsius"
        };
        weather.temprature.value = Math.floor(data.main.temp - KELVIN);
        weather.description = data.weather[0].description;
        weather.iconId = `http://openweathermap.org/img/w/${data.weather[0].icon}.png`;
        weather.city = data.name;
        weather.country = data.sys.country;          
    
    
        dispatch({
            type: "UPDATE_WEATHER",
            payload: weather
        });
    };
    
    export const KEY = "This is the key from your account openweather";
    
    export const KELVIN = 273;
    
    const reducer = (state, action) => {
        const { type, payload } = action;        
        switch (type) {                     
            case "SET_ERROR": 
                return {
                    ...state,
                    error: payload.error,
                    city: payload.city,
                    weather: null
                };
            case "SET_LOCATION":
                return {
                    ...state,
                    latitude: payload.latitude,
                    longitude: payload.longitude
                };
            case "UPDATE_WEATHER":
                return {
                    ...state,                
                    weather: payload,
                    error: null,
                    city: payload.city
                };
            default:
                return state;
        }
    };
    
    export default reducer;
    
  • getWeather 비동기식 이벤트를 실행하여 개방된 날씨로부터 데이터를 가져오고 제공된 URL을 매개 변수로 사용
  • updateWeather dispatch 방법으로 getWeather에서 되돌아오는 데이터를 필요에 따라 포맷하고 dispatch 상태 값을 업데이트하는 방법.
  • reducer 상태로 업데이트할 모든 작업과 유효 부하 데이터를 정의합니다.여기 총 세 가지 동작이 있어요
  • SET_ERROR 알림 구성 요소가 날씨
  • 를 가져올 수 없을 때 오류 메시지를 표시합니다
  • SET_LOCATION 위도와 경도 값이 현재 위치에서 설정됩니다. 이것은 일회성 설정입니다.위치 아이콘
  • 을 클릭하면 값이 재사용됩니다.
  • UPDATE_WEATHER 상태의 날씨 정보를 업데이트하여 구성 요소에 표시
    # 생성 상태 제공(스토리지)store 디렉토리에 새 폴더src를 만듭니다.
    그리고 index.js 폴더 아래에 새로 만들기store.
    다음 코드를 index.js 파일에 복사합니다
  • import React, { createContext, useContext, useReducer } from 'react';
    import reducer from '../reducers';
    
    export const initialState = {
        weather: null,
        latitude: 0.0,
        longitude: 0.0,
        city: "",
        error: null
    };
    
    export const StateContext = createContext(initialState);
    const { Provider } = StateContext;
    
    export const StateProvider = ({children}) => {
        return <Provider value={useReducer(reducer, initialState)}>{children}</Provider>;
    };
    
    export const useStateValue = () => useContext(StateContext);
    
  • initialState는 상태
  • 의 초기값입니다.
  • reducer는 우리의 감속기
  • 에 의해 정의된 것이다
  • useContext 컨텍스트의 현재 컨텍스트 값을 반환합니다.
    # 국가에서 제공하는 리소스 활용index.js 폴더 아래의 src를 열고 스크립트 내용을 업데이트합니다. 아래와 같습니다.
  • import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './App';
    import reportWebVitals from './reportWebVitals';
    import { StateProvider } from './store';
    
    ReactDOM.render(
      <React.StrictMode>
        <StateProvider>
          <App />
        </StateProvider>
      </React.StrictMode>,
      document.getElementById('root')
    );
    
    // If you want to start measuring performance in your app, pass a function
    // to log results (for example: reportWebVitals(console.log))
    // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
    reportWebVitals();
    
    App 구성 요소가 현재 StateProvider 구성 요소에 둘러싸여 있습니다.이것은 전체 응용 프로그램에 상태를 사용할 수 있도록 합니다.

    알림 구성 요소 추가


    알림 구성 요소는 오류 메시지를 표시하는 데 사용됩니다.Notification.js 디렉토리에 새 파일 만들기src
    import React from 'react';
    import { useStateValue } from './store';
    
    function Notification() {    
    
        const [{error, city}] = useStateValue();  
    
        return (
            <div className="notification">
                {error && <p>{error.message}, <b><i>"{city}"</i></b> is not a valid city</p>}
            </div>
        )
    }
    
    export default Notification
    
    
    const [{error, city}] = useStateValue(); 글로벌 상태에서 데이터에 액세스할 수 있습니다.

    제목/도시 구성 요소 추가


    Header/City 구성 요소는 제목 메시지와 도시 이름을 입력할 수 있는 입력 필드를 표시하는 데 사용됩니다.또한 사용자 시스템의 현재 위치로 다시 설정할 수 있는 버튼 아이콘도 포함되어 있습니다.City.js 디렉토리에 새 파일 만들기src
    import React, { useState, useEffect } from 'react';
    import { MapPin } from 'react-feather';
    import { useStateValue } from './store';
    import { getWeather, KEY, updateWeather } from './reducers';
    
    function CityInfo() {
        const [currentCity, setCurrentCity] = useState('');
        const [{city, latitude, longitude}, dispatch] = useStateValue();    
    
        useEffect(() => {
            setCurrentCity(city);
        }, []);
    
        /**
         * Use click on the location button to see the weather
         * at the current location
         */
        const defaultLocation = () => {
            let api = `http://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&appid=${KEY}`;
            getWeatherData(api);
        };
    
        /**
         * Key up event to capture keyboard
         * Firing to update the city in the store if the key is Enter
         */
        const onCityChange = (event) => {
            if (event.keyCode === 13) {
                event.preventDefault();           
                let api = `http://api.openweathermap.org/data/2.5/weather?q=${currentCity}&appid=${KEY}`;    
                getWeatherData(api);
            }
        };
    
        const getWeatherData = (api) => {
            getWeather(api)
            .then((data) => {    
                setCurrentCity(data.name); 
                updateWeather(dispatch, data);
            })
            .catch (e => {            
                dispatch({
                    type: "SET_ERROR",
                    payload: {
                        error: e,
                        city: currentCity
                    }
                }); 
            }); 
        };
    
        /**
         * Handle the input change
         */
        const handleChange = (event) => {
            setCurrentCity(event.target.value);
        }
    
        return (
            <div className="app-title">
                <p>Weather Info</p>
                <input type="text" placeholder="Enter the city" autoComplete="off" 
                onChange={handleChange}
                value={currentCity} onKeyUp={onCityChange} />
                <div className="location-icon" onClick={defaultLocation}>
                    <MapPin />
                </div>        
            </div>
        )
    }
    
    export default CityInfo;
    
    const [currentCity, setCurrentCity] = useState(''); 입력 필드에 입력한 값을 유지합니다.const [{city, latitude, longitude}, dispatch] = useStateValue(); 글로벌 상태에서 데이터에 액세스할 수 있습니다.dispatch가 상태와 짝을 짓는 방법이라면dispatch은 리셋 방법에 전달되어 상태를 갱신한다.

    WeatherInfo 구성 요소 추가


    WeatherInfo 구성 요소는 날씨 데이터를 표시하는 데 사용됩니다.WeatherInfo.js 디렉토리에 새 파일 만들기src
    import React from 'react';
    import { useStateValue } from './store';
    
    function WeatherInfo() {
        const [{weather}] = useStateValue();
    
        return weather && (
            <div className="weather-container">
                <div className="weather-icon">
                  <img src={weather.iconId} alt={weather.description} />
                  <div className="temprature-value">
                    <p>{weather.temprature.value} *<span>C</span></p>
                  </div>
                  <div className="temprature-description">
                    <p>{weather.description}</p>
                  </div>
                  <div className="location">
                    <p>{weather.city}, {weather.country}</p>
                  </div>
                </div>          
            </div>
        )
    }
    
    export default WeatherInfo;
    
    
    const [{weather}] = useStateValue(); 전 세계 상태의 날씨 데이터에 접근할 수 있습니다.

    응용 프로그램을 업데이트합니다.js


    현재 우리는 모든 구성 요소가 있습니다. 우리는 그것들을 메인 프로그램 구성 요소에 추가할 것입니다
    import React, { useEffect } from 'react';
    import './App.css';
    import { useStateValue } from './store';
    import Notification from './Notification';
    import WeatherInfo from './WeatherInfo';
    import CityInfo from './CityInfo';
    import { getWeather, KEY, updateWeather } from './reducers';
    
    function App() {
      const [{error}, dispatch] = useStateValue();  
    
      useEffect(() => {     
        if ("geolocation" in navigator) {
          navigator.geolocation.getCurrentPosition((position) => {  
            let payload = {
              latitude: position.coords.latitude,
              longitude: position.coords.longitude
            };
            dispatch({
              type: "SET_LOCATION",
              payload
            });
            let api = `http://api.openweathermap.org/data/2.5/weather?lat=${payload.latitude}&lon=${payload.longitude}&appid=${KEY}`;
            getWeather(api)
            .then((data) => {
              updateWeather(dispatch, data);          
            })
            .catch (e => {            
                dispatch({
                  type: "SET_ERROR",
                  payload: {
                    error: e
                  }
                });
            });                   
          }, (error) => {  
            dispatch({
              type: "SET_ERROR",
              payload: {
                error
              }
            });              
          });
        }
      }, []);  
    
      return (    
        <div className="app">      
          <CityInfo />
          {error && <Notification />}
          {!error && <WeatherInfo />}
        </div>
      );
    }
    
    export default App;
    
  • navigator.geolocation.getCurrentPosition 사용자의 현재 위치를 가져올 수 있습니다. 이것은 위치를 방문하기 위해 시작할 때 메시지를 알립니다.
  • {error && <Notification />} 오류가 발생하면 렌더링됩니다.
  • {!error && <WeatherInfo />} 오류가 없으면 렌더링
  • 축하합니다!!!


    축하합니다!!!날씨 응용 프로그램 구축을 처음부터 끝까지 끝냈습니다.

    좋은 웹페이지 즐겨찾기