React JS ile Basit Bir Form Upload

Merhaba, yeni yeni react js öğrenmeye başladım. Küçük küçük denemeler ile ilerlemeye çalışıyorum. Aklıma estikçe buradan kodları paylaşacağım. 

Şimdiden söyleyeyim birçok kişiye göre çok basit gelebilir. Onlar okumaya devam etmesinler. laugh

Hadi başlayalım. 

İlk olarak, aşağıdaki kodu konsol ekranında yazarak bir proje oluşturalım. 

npx create-react-app file_upload

file_upload adında bir dosya oluşturuldu. Bu dosyayı VsCode ile açalım.

Çok zorlamayacağım. İşlemlerimizi App.js içinde yapacağız. 

Öncelikle axios u kurarak başlayalım. Konsol ekranına aşağıdaki kodu girerek bu paketi indirebilirsiniz.

npm i axios --save

Burada --save komutu opsiyonel. 

App.js dosyasını açalım ve içini temizleyelim. 

import React from "react";
function App() {
  return <div className="App"></div>;
}

export default App;

Ardından projeyi başlatalım.

npm start

Evet, görüldüğü üzere kalbimiz kadar temiz bir sayfa bizi karşılayacak. 

 

Devam edelim. 

Önce görsel kısım ile başlayalım. Ben şu şekilde yaptım. Basit ve çirkin. 

return (

    <div className="App">
      
     Name:
      <input
        type="text"
        name="name"
       
      />
      
     Price:
      <input
        type="text"
        name="price"
        
      />
      
      Görsel:
      <input type="file"  name="dosya" />
     
      <button>Upload</button>
);

Ardından state lerimizi tanımlıyoruz.

  const [selectedFile, setSelectedFile] = useState(null);
  const [name, setName] = useState("");
  const [price, setPrice] = useState(0);

Sonrasında, inputlarımıza onChange event i ekleyelim. 

Bende son durum şöyle oldu.

return (

    <div className="App">
     
      Name:
      <input
        type="text"
        name="name"
        onChange={(e) => setName(e.target.value)} // Burada name state ine atama yapıyoruz.
      />
     
      Price:
      <input
        type="text"
        name="price"
        onChange={(e) => setPrice(e.target.value)} // Burada price state ine atama yapıyoruz.
      />
     
      Görsel:
      <input type="file" onChange={fileSelectedHandler} name="dosya" /> 
      

      <button onClick={uploadHandler}>Upload</button>
      
    </div>
  );
}

 

fileSelectedHandler metounu yazalım ve içinde de selectedFile state ine atamasını yapalım.

  const fileSelectedHandler = (e) => {
    
     const file = e.target.files[0]; // Yüklenece dosyayı buradan alıyoruz

     setSelectedFile(file); // state e atama yapıyoruz. 
  };

 

Daha sonra button a atanan metodu yani uploadHandler metodunu yazalım. 

const uploadHandler = async () => {
    
    const formData = new FormData(); // Yeni bir form data türetiyoruz.

    
    // Yüklenen elemanları tek tek ekliyoruz. Tabi ki state lerindeki değerlere göre
    formData.append("dosya", selectedFile);
    formData.append("name", name);
    formData.append("price", price);

    const post = await axios
     
      .post("http://localhost:8000/api/product", formData)
     
      .then((res) => {
          
          setSonuc(res.data);
      })
      
      .catch((err) => {
     
        setHata(err);
      });
  };

Anlaşılacağı üzere, iki yeni state ekledik .Api den gelen değerleri bu state lere atıyoruz.

  const [hata, setHata] = useState("");
  const [sonuc, setSonuc] = useState();

 

En sonunda da hadi gelen saçma da olsa ekranda gösterelim. 

Görsel kısımdaki çirkinliği biraz daha arttıralım. 

  return (
    
    <div className="App">
    
      Name:
      <input
        type="text"
        name="name"
        onChange={(e) => setName(e.target.value)}
      />
     
      Price:
      <input
        type="text"
        name="price"
        onChange={(e) => setPrice(e.target.value)}
      />
      
      Görsel:
      <input type="file" onChange={fileSelectedHandler} name="dosya" />
      

      <button onClick={uploadHandler}>Upload</button>
      
      // Aşağıdaki kısımları ekledik
      {sonuc?.durum === "success" && (
        <div>
          <h2>Sonuc</h2>
          <p>
            <img src={sonuc.image} alt={sonuc.name} width="400" />
          </p>
          <p>{sonuc.name}</p>
          <p>{sonuc.price}</p>
        </div>
      )}
      {sonuc?.durum === "hata" && (
        <div>
          <h1>HATA</h1>
          <p> { sonuc.sonuc } </p> // Buraya takılmayın, api den sonuc diye bir sey donduruyorum.
        </div>
      )}

    
      // Hata olursa burası çalışacak.
      {hata && ( 
        <div>
          <h1>HATA</h1>
          <p>{hata}</p>
        </div>
      )}


    </div>
  );

 

App.js dosyasının son hali aşağıdaki gibidir. 

import React, { useState } from "react";
import axios from "axios";

function App() {

  const [selectedFile, setSelectedFile] = useState(null);
  const [name, setName] = useState("");
  const [price, setPrice] = useState(0);

  const [hata, setHata] = useState();
  const [sonuc, setSonuc] = useState();

  const fileSelectedHandler = (e) => {

    const file = e.target.files[0];

    setSelectedFile(file);

  };

  const uploadHandler = async () => {

    const formData = new FormData();

    formData.append("dosya", selectedFile);
    formData.append("name", name);
    formData.append("price", price);

    const post = await axios
      .post("http://localhost:8000/api/product", formData)
      .then((res) => {

        setSonuc(res.data);

      })
      .catch((err) => {
     
        setHata(err);

      });
  };

  return (
    <div className="App">
      
     Name:
      <input
        type="text"
        name="name"
        onChange={(e) => setName(e.target.value)}
      />
      
     Price:
      <input
        type="text"
        name="price"
        onChange={(e) => setPrice(e.target.value)}
      />
      
      Görsel:
      <input type="file" onChange={fileSelectedHandler} name="dosya" />
     
  
      <button onClick={uploadHandler}>Upload</button>
    
      {sonuc?.durum === "success" && (
        <div>
          <h2>Sonuc</h2>
          <p>
            <img src={sonuc.image} alt={sonuc.name} width="400" />
          </p>
          <p>{sonuc.name}</p>
          <p>{sonuc.price}</p>
        </div>
      )}
     
      {sonuc?.durum === "hata" && (
        <div>
          <h1>HATA</h1>
          <p>{sonuc.sonuc}</p>
        </div>
      )}

      {hata && (
        <div>
          <h1>HATA</h1>
          <p>{hata}</p>
        </div>
      )}
    </div>
  );
}

export default App;

 

Merakınızı gidermek için Laravel kısmına bakalım. 

Öncelikle, routes dizini altındaki api.php dosyasını açalım ve kısaca şunu yazalım. 

Route::apiResource('product', 'ProductController');

Tabiki Product adında bir modelimiz var. 

Tabiki ProductController adında bir controller ımız var.

Efsane olan migration dosyamız şu şekilde. 

Schema::create('products', function (Blueprint $table) {

     $table->id();
     $table->string('name');
     $table->float('price');
     $table->text('image')->nullable();

     $table->timestamps();
});

 

Benim amacım sadece dosya yüklemek olduğu için controller içinde de  store metodunu kullandım. Laravel biliyorsanız tanıdık gelecektir. 

public function store(Request $req)
{

    // En azından ver diger veriler boş gelmesin.
	if ( $req->name == "" || $req->price == "" ) {
		$sonuc = [
			"durum" => "hata",
			"sonuc" => "Lütfen boş alan bırakmayınız",
		];
		return response()->json($sonuc);
	}

    // Kaydetme işlemi başlıyor.
	$product = new Product();

	if ( $req->hasFile('dosya') ) {


		$dosyaAdi = $req->file('dosya')->getClientOriginalName();

		$filePath = "uploads/images/".$dosyaAdi;

        // Storage altına yüklüyoruz. 
		Storage::disk('public')->put($filePath, File::get($req->file('dosya')));

		$product->image  = $dosyaAdi;

		$product->name = $req->name;
		$product->price = $req->price;
		$product->save();


		$sonuc = [
			"durum" => "success",
			"sonuc" => "Ürün başarıyla eklendi",
			"name" => $product->name,
			"price" => $product->price,
			"image" => url(Storage::url($filePath))
		];

		return response()->json($sonuc);
	}else {

		$sonuc = [
			"durum" => "error",
			"sonuc" => "Bir sorun oluştu"
		];
		return response()->json('Lütfen bir dosya yükleyiniz!');
	}



}

 

Tabi Laravelde Storage içini kullanabilmek için şu komutu çalıştırmayı unutmuyoruz. 

php artisan storage:link

Çünkü dönen response içinde yüklediğimiz görselin de yolunu belirtiyoruz. Aksi halde gözükmez. 

 

Evet, sanırım hepsi bu kadar. 

Bir acemi için fena sayılmaz sanırım. Öğrendikçe daha da güzel kodlar yazılır.

Neyse ben kaçayım.

Kolay gelsin. 

 

1510 Görüntülenme

Yorum Yap