useState
hook'u nedir ve nasıl kullanılır?
useState
, React ile birlikte gelen çok kullanışlı bir hook'tur. Ancak kullanımına geçmeden önce bu hook'un kullanımında dikkat edilmesi gereken birkaç noktaya (veya uyulması gereken kurallara) değinelim.
1. useState
hook'u yalnızca functional component
'ler ile kullanılır. Yani, class component
'ler ile kullanmaya kalktığımızda hata alırız. Peki functional component
nedir? Create-react-app
kurduğumuzda gelen App.js
dosyasını temizleyip aşağıdaki hale getirelim:
function App (props) {
return <h1>Hello, {props.name}</h1>;
}
Görüleceği üzere bir functional component
, props
ve return
alan bir fonksiyondur. Yukarıdaki örneğin aynısını class component
olarak yazmak istersek şöyle bir şey yazmamız gerekirdi:
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
Biz bir functional component
'in içerisine hook yazabilirken; class component
'in içerisine yazamayız. Dolayısıyla dikkat edilmesi gereken ilk şey, useState
hook'unu functional component
'ler içerisinde kullanmaktır.
2. useState
hook'unu bir if
ifadesine veya for
vb. gibi bir döngünün içerisine ekleyemeyiz. Yani, aşağıdaki gibi bir kullanım bize hata verecektir:
import { useState } from "react";
function App() {
if (true) {
useState();
}
return (
<div className="App">
hello
</div>
);
}
export default App;
Alacağımız hata ise şöyle olacaktır:
React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render.
Sonuç olarak hook'ları,
- Bir
if
ifadesinin içerisinde kullanamayız, - Bir
for
döngüsünün (genel olarak birloop
'un) içerisinde kullanamayız, - Bir
fonksiyon
'un içerisinde kullanamayız.
Yani hook'lar herhangi bir ifade ile iç içe geçemez (nested). Bir functional component
'in içerisinde yalnızca top-level olarak kullanılabilirler.
Tüm bu kurallardan sonra asıl soruya gelelim: useState
hook'u nedir ve nasıl kullanılır? Öncelikle useState
hook'unun sentaksını, yani biçimini/formunu gösterelim:
import { useState } from "react";
function App() {
const [state, setState] = useState(initialState);
return (
<div className="App">
{state}
</div>
);
}
React useState
hook'u, bir functional component
'teki state
'i / durum
'u / hâl
'i takip etmemize/izlememize olanak tanır. state
genellikle bir uygulamada takip edilmesi/izlenmesi gereken verileri veya özellikleri ifade eder.
Yukarıdaki kodda ilk olarak destructuring { ... }
kullanarak react
içerisinden useState
'i dosyamıza dahil ettik.
useState
bir initial state
alır ve iki değer döndürür:
- Şu anki
state
, -
state
'i güncelleyen bir fonksiyon.
Dolayısıyla biz useState
kullanırken bir array
içerisinde bunları yazarız. useState
hook'unun içerisine de o state
'in başlangıç hâli
'ni, yani initial state
'i yazarız. Bu initial state
herhangi bir değer olabilir: string
, number
, array
, object
, boolean
vb. Meselâ şöyle bir kodumuz olsun:
import { useState } from "react";
function FavoriteColor() {
const [color, setColor] = useState("");
}
İlk değer olan color
, mevcut state
'imizdir.
İkinci değer olan setColor
, state
'imizi güncellemek için kullanılan fonksiyondur.
Son olarak, initial state
'i boş bir string
olarak ayarladık: useState("")
. Dolayısıyla color
adındaki state
'in şu anki değeri boş bir string
şeklindedir.
Bu initial state
'i meselâ useState("red")
şeklinde de ayarlayabilirdik. Bu durumda color
adındaki state
'in şu anki değeri red
olurdu:
import { useState } from "react";
function FavoriteColor() {
const [color, setColor] = useState("red");
return <h1>En sevdiğim renk {color}!</h1>
}
Ekranımızda şöyle bir şey görecektik: En sevdiğim renk red!
Peki setColor
fonksiyonunu nasıl kullanabilir ve color
adındaki state
'in aldığı değeri değiştirebiliriz? Bir button
ekleyelim ve bu button
'a da bir onClick
event'i ekleyelim:
import { useState } from "react";
function FavoriteColor() {
const [color, setColor] = useState("red");
return (
<>
<h1>My favorite color is {color}!</h1>
<button
type="button"
onClick={() => setColor("blue")}
>Blue</button>
</>
)
}
İçerisinde onClick
event'i olan bir button
ekledik. Bu button
'a tıkladığımızda color
adındaki state
'in değeri blue
değerini alacaktır. Çünkü onClick
event'i içerisinde setColor
fonksiyonunu çağırdık ve blue
değerini verdik. Yani aslında setColor
fonksiyonuyla biz şunu demiş/yapmış oluyoruz: color
adındaki state
'in değerini blue
olarak güncelle (set et).
Yukarıda da belirttiğimiz üzere, bir useState
hook'u string
'leri, number
'ları, boolean
'ları, array
'leri, object
'leri ve bunların herhangi bir kombinasyonunu takip etmek için kullanılabilir! Aşağıdaki örneğe bakalım:
import { useState } from "react";
function Car() {
const [brand, setBrand] = useState("Ford");
const [model, setModel] = useState("Mustang");
const [year, setYear] = useState("1964");
const [color, setColor] = useState("red");
return (
<>
<h1>Şu arabaya sahibim: {brand}</h1>
<p>
Arabam {color} renginde ve modeli şu: {year} {model}.
</p>
</>
)
}
Yukarıdaki örnekte useState
hook'larını kullanarak brand
, model
, year
ve color
özelliklerini takip ediyoruz. Bu özelliklerin her biri bir state
'dir. Bu state
'lerin değerlerini de setBrand
, setModel
, setYear
ve setColor
fonksiyonlarıyla güncelleyebiliyoruz. Yukarıdaki kod bize şu çıktıyı verecektir:
Şu arabaya sahibim: Ford
Arabam red renginde ve modeli şu: 1964 Mustang.
Yukarıdaki gibi multiple state
, yani birçok state
'ten oluşan bir kod yazmak yerine aynı şeyi bir object
ve bir hook
kullanarak da yapabilirdik:
import { useState } from "react";
function Car() {
const [car, setCar] = useState({
brand: "Ford",
model: "Mustang",
year: "1964",
color: "red"
});
return (
<>
<h1>Şu arabaya sahibim: {car.brand}</h1>
<p>
Arabam {car.color} renginde ve modeli şu: {car.year} {car.model}.
</p>
</>
)
}
Bu kodla da aynı çıktıyı almış olurduk.
Bir state
İçerisindeki objects
'i veya arrays
'i Güncellemek
Bir state
güncellendiğinde, aslında, bu state
tüm state
'in üzerine yazılır.
Peki ya sadece arabamızın rengini güncellemek istiyorsak?
Sadece setCar({color: "blue"}) yazarsak, bu setCar
fonksiyonu brand
, model
ve year
'ı halihazırda mevcut olan state
'imizden kaldıracaktır. Bir örnek kod üzerinden ne olduğunu daha iyi göstermiş olalım:
import { useState } from "react";
function App() {
const [car, setCar] = useState({
brand: "Ford",
model: "Mustang",
year: "1964",
color: "red"
});
const updateColor = () => {
setCar( {color: "blue" });
}
return (
<>
<h1>My {car.brand}</h1>
<p>
It is a {car.color} {car.model} from {car.year}.
</p>
<button
type="button"
onClick={updateColor}
>Blue</button>
</>
)
}
export default App;
Yukarıdaki kodu çalıştırdığımızda şu çıktıyı alacağız:
My Ford
It is a red Mustang from 1964.
Blue (button)
Ekrandaki Blue
button'ına tıkladığımızda, çıktımız şu hâli alacaktır:
My
It is a blue from .
Blue (button)
Görüleceği üzere, setCar
fonksiyonu, brand
, model
ve year
'ı kaldırmıştır. Yani, sadece color
özelliğini güncellemek istedik ancak setCar
fonksiyonu, tüm state
'in üzerine yalnızca color
özelliğini yazdı ve diğer tüm özellikleri kaldırdı. Bunun olmasını istemeyiz. Bu yüzden brand
, model
ve year
'ı tekrar eklememiz gerekiyor. Bu işlemi yapmak için JavaScript'teki spread
operatörünü kullanabiliriz:
import { useState } from "react";
function App() {
const [car, setCar] = useState({
brand: "Ford",
model: "Mustang",
year: "1964",
color: "red"
});
const updateColor = () => {
setCar(previousState => {
return { ...previousState, color: "blue" }
});
}
return (
<>
<h1>My {car.brand}</h1>
<p>
It is a {car.color} {car.model} from {car.year}.
</p>
<button
type="button"
onClick={updateColor}
>Blue</button>
</>
)
}
export default App;
Buradaki dikkat etmemiz gereken updateColor
şeklindeki fonksiyon içerisinde çağırdımız setCar
hook'unun aslında spread
operatörüyle birlikte bir callback
fonksiyon aldığı. Bu örnekte, setCar
hook'u içindeki previousState
isimli bir callback
fonksiyon kullanılmaktadır. Bu fonksiyon, setCar
tarafından geçerli olan önceki state
'i temsil eder ve yeni bir state
döndürmek için kullanılır. updateColor
fonksiyonu, setCar
fonksiyonunu çağırdığında, mevcut state
'i almak için bu callback
fonksiyonu kullanır ve mevcut state
ile birlikte, yani mevcut state
'i muhafaza ederek yeni bir state
döndürür.
Özetlemek gerekirse: setCar
fonksiyonuna bir callback
fonksiyonu (yani, previousState
) geçirilir. Bu callback
fonksiyonu, mevcut state
'i alır ve bu state
'in bir kopyasını oluşturarak color
özelliğini blue
olarak değiştirir. Bu yeni state
, setCar
fonksiyonu tarafından aktif hale getirilir ve component yeniden render edilir.
Dolayısıyla biz ekrandaki Blue
butonuna tıkladığımızda bir önceki bilgiler, yani brand
, model
ve year
kaybolmamış olur. Çünkü setCar
fonksiyonu, mevcut state
'i muhafaza ederek ve yalnızca color
özelliğini güncelleyerek yeni bir state
döndürür.
useState
hook'unun class component
'ler ile karşılaştırmalı ve daha detaylı bir şekilde anlatıldığı şu yazıyı okumanızı tavsiye ederim:
Top comments (0)