React JS ile Basit Bir Hava Durumu Uygulaması

Merhaba, bu yazıda react.js ile openweathermap.org adresinden alınan key ile basit bir hava durumu uygulaması yapacağız.

Öncelikle belirteyim, üye değil iseniz https://openweathermap.org adresine üye olun. Buradan bir tane api key oluşturmanız gerekiyor. Şu adresten halledebilirsiniz. 

O zaman başlayalım.

Projemizde,  bootstrap ve fontawesome kullanacağımız için public/index.html dosyasına ekleme cdn üzerinden aldığımız linki buraya yapıştıralım. 

 head tagları içine şu satırları yerleştirelim. 

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css"
integrity="sha512-5A8nwdMOWrSz20fDsjczgUidUBR8liPYU+WymTZP1lmY9G6Oc7HlZv156XqnsgNUzTyMefFTcsFH/tnJE/+xBg=="
    crossorigin="anonymous" />

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css"
    integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">

body tagı kapatılmadan hemen önce de şu satırları yapıştıralım.

<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
    integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>


<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns" crossorigin="anonymous"></script>

 

Projemizi oluşturduktan sonra src klasörü içine components adında bir tane klasör oluşturalım.

İçerisine de şu isimlerde dosyaları oluşturalım. 

  1. Loading.js
  2. Search.js
  3. Sonuc.js
  4. SonucList.js

Ardından axios u projemize kuralım.  Bilmeyenler için kodu aşağıda:

npm i axios --save

Şimdi App.js içinde diğer component leri çağıracağımız için öncelikle Search.js dosyasını açalım ve içine aşağıdaki kodları yapıştıralım.

import React from "react";

const Search = ({ handleOnSubmit, sehir, setSehir }) => {

  return (
    <div className="row">
      <div className="col-md-12">
        <form className="mt-5" onSubmit={handleOnSubmit}>
          <div className="form-group row">
            <label htmlFor="sehir" className="col-sm-1 col-form-label">
              Şehir:
            </label>
            <div className="col-sm-11">
              <input
                type="text"
                className="form-control"
                id="sehir"
                value={sehir}
                onChange={(e) => setSehir(e.target.value)}
              />
            </div>
          </div>

          <div className="form-group row pl-1 offset-sm-1  ">
            <button type="submit" className="btn btn-primary btn-lg  ">
              Sorgula
            </button>
          </div>
        </form>
      </div>
    </div>
  );
};

export default Search;

 

Anlaşıldığı üzere, Search component i, App.js dosyasından 3 tane props alıyor. 

Props demişken hemen App.js içinde state lerimizi tanımlayalım ki search component ine gönderebilelim.

const [sehir, setSehir] = useState(""); // input alanından gelecek değeri burada tutacağız
const [sonuc, setSonuc] = useState([]); // api den gelen değerleri burada tutacağız
const [loading, setLoading] = useState(false); // api den sonuç gelene kadar loading gösterelim.

loading state i, tahmin edileceği üzere Loading component inin gösterilip gösterilmeyeceğini belirliyor.

O zaman hemen Loading.js dosyamızı yazalım.

import React from "react";

const Loading = () => {

  return (

    <div className="d-flex justify-content-center">
      <div className="spinner-border" role="status">
        <span className="sr-only">Loading...</span>
      </div>
    </div>

  );
};

export default Loading;

 

Ana dizinde, .env adında bir dosya oluşturalım ve içine openweatherapp den aldığımız key i yazalım. 

REACT_APP_OPEN_WEATHER_API=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Şimdi, arama kısmını yaptığımıza göre App.js içinde handleOnSubmit() metodunu yazalım.

const handleOnSubmit = (e) => {
 
   e.preventDefault();

   // Boş değer yollamasınlar
   if (sehir.trim() === "") return alert("Lütfen bir şehir adı yazınız");

   setLoading(true);

   // axios ile verimizi çekiyoruz. 
   axios
    .get(`http://api.openweathermap.org/data/2.5/find?q=${sehir}&lang=tr&units=metric&&cnt=5&appid=${process.env.REACT_APP_OPEN_WEATHER_API}`)
      
    .then((res) => {
        
       let donenDeger = res.data.list;
        
        setLoading(false);     // loading durdurulsun

        setSonuc(donenDeger);  // gelen sonucu sonuc state ine atalım.

      })

      .catch((err) => {

        setLoading(false);
        console.log(err);

      });
  };

 

Evet, api den cevap geldi. Gelen cevabı setSonuc ile sonuc state ine attık.

Şimdi Sonuc.js dosyamızı açalım ve içine şunları yapıştıralım.

import React from "react";
import SonucList from "./SonucList";

const Sonuc = ({ sonuc }) => {

  return (

    <div className="row justify-content-center">

      {sonuc.map((item) => (
        <SonucList item={item} key={item.id} />
      ))}

    </div>

  );
};

export default Sonuc;

Tahmin edileceği üzere, App component inden sonuc props u alıyor. Yani dönen değeri bu component e gönderiyoruz.

Sonuc component i içinde de gelen sonucu listelemek için bir  döngü oluşturuyoruz ve her elemanı SonucList component inde bastırıyoruz.

Hemen SonucList component ini yazalım. 

import React from "react";

const SonucList = ({ item }) => {

  return (

    <div className="col-lg-6 col-md-6 mb-3">

      <div className="card p-4">
        <div className="d-flex">
          <h6 className="flex-grow-1 text-center sehirAdi">
            {item.name} - {item.sys.country}
          </h6>
        </div>

        <div className="d-flex flex-column temp mt-5 mb-3">
          <h1 className="mb-0 font-weight-bold" id="heading">
            {Math.ceil(item.main.temp)}° C{" "}
          </h1>
          <span className="small grey description">
            {item.weather[0].description}
          </span>
        </div>

        <div className="d-flex">
          <div className="temp-details flex-grow-1">
            <p className="my-1">
              <img
                src="https://i.imgur.com/B9kqOzp.png"
                height="17px"
                alt="Rüzgar hızı"
              />
              <span>&nbsp; {Math.ceil(item.wind.speed * 3.6)} km/saat</span>
            </p>

            <p className="my-1">
              <i className="fa fa-tint mr-2" aria-hidden="true"></i>
              <span> {item.main.humidity} % </span>
            </p>
          </div>

          <div>
            <img
              src={`http://openweathermap.org/img/wn/${item.weather[0].icon}@2x.png`}
              alt="Hava durumu"
              width="100px"
            />
          </div>

        </div>

      </div>

    </div>
  );
};

export default SonucList;

 

Api'den gelen değerleri, ekrana bastırıyoruz. 

App.js içini şu şekle getirelim.

import React, { useState } from "react";

import axios from "axios";

import Search from "./components/Search";
import Sonuc from "./components/Sonuc";
import Loading from "./components/Loading";

function App() {
  const [sehir, setSehir] = useState("");
  const [sonuc, setSonuc] = useState([]);
  const [loading, setLoading] = useState(false);

  const handleOnSubmit = (e) => {

    e.preventDefault();

    if (sehir.trim() === "") return alert("Lütfen bir şehir adı yazınız");

    setLoading(true);
    axios.get(
        `http://api.openweathermap.org/data/2.5/find?q=${sehir}&lang=tr&units=metric&&cnt=5&appid=${process.env.REACT_APP_OPEN_WEATHER_API}`
      )
      
      .then((res) => {

        let donenDeger = res.data.list;
        setLoading(false);
        setSonuc(donenDeger);
      })

      .catch((err) => {
        setLoading(false);
        console.log(err);
      });
  };

  return (

    <div className="App">

      <div className="container">

       {/** Search component ine metodumuzu ve state lerimizi gönderiyoruz.  */}
        <Search
          handleOnSubmit={handleOnSubmit}
          sehir={sehir}
          setSehir={setSehir}
        />

        {/** Loading true ise sonuc gelmemiştir, Loading componentini gösterelim.
         * Sonuc varsa ve sonuc dizisinde eleman varsa Sonuc componentine gidiyoruz. */}

        { loading ? <Loading /> : sonuc.length > 0 && <Sonuc sonuc={sonuc} />}

      </div>
    </div>
  );
}

export default App;

 

Projenin tam halini buradan  erişebilirsiniz. 

Ha unutmadan söyleyeyim. Tasarım olarak da şuradaki arkadaşın kodlarını kullandım. 

Evet, aslında basit bir şey ama benim gibi yeni başlayanlara belki bir fikir olur dedim.

Hepsi bu kadar...

 

 

118 Görüntülenme

Yorum Yap