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.
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.
Yorum Yap