React State Management — Zustand Kullanımı

Selim KURT
5 min readJun 13, 2024

--

State Management, yalnızca durum değiştiğinde yeniden render edilen React uygulamasının önemli yönleri oluşturur. Bir durum, bileşen hakkında veri veya bilgi içerebilir. Uygulamanız büyüdükçe, bileşenler arasında durumu ve veri akışını yönetmek kritik hale gelir.

React Durum Yönetimi

Bir React uygulamasının durumunu birkaç şekilde yönetebilirsiniz.

  • React Yerel Durum Yönetimi: useState, useReducer, useRef, useContext ve özel hooklar gibi hooklar yerel durum yönetimini destekler.
  • Dolaylı Durum Yöneticileri: React Router ve React Query gibi harici kütüphaneler. Bunlar esas olarak durum yönetimi için kullanılmaz, ancak yerel bir hook ile birleştirildiğinde durumu iyi bir şekilde yönetebilirler.
  • Doğrudan Durum Yöneticileri: Yalnızca durum yönetimi için kullanılan üçüncü parti kütüphaneler. Redux, Zustand, Jotai ve Valtio bu kategoriye girer.

Zustand Nedir?

Zustand, bir durum yönetim kütüphanesidir. Kompakt, hızlı ve ölçeklenebilir bir sistemdir. Daha az boilerplate kodu ile oldukça basit bir sistemdir. Redux ve benzeri kütüphanelerden daha az kodla React durumlarını yönetmek için kullanabilirsiniz. Bir sağlayıcıya (provider) bağımlı değildir, bu nedenle daha az React mantığı kodlamanız gerekir ve bu, unutma eğiliminde olduğumuz şeyleri azaltabilir. Basitleştirilmiş flux prensiplerine dayanır ve ağırlıklı olarak hooklar kullanır.

Neden Zustand?

  • Daha hızlıdır: Durumun belirli bir dilimini seçme seçeneği sunar.
  • Durum birleştirme: Durumu varsayılan olarak birleştirir. Bir nesne durumunun tek bir özelliğini güncellemeyi düşünün, {x:1, y:2}. Doğrudan {y:3} ayarlayabilirsiniz. Zustand verileri sizin için birleştirecektir. Eski durumu dağıtmanıza ve özellikleri güncellemenize gerek yoktur: {…state, y:3}.
  • Genişletilebilir: Çeşitli middleware türlerini kullanabilirsiniz.
  • Daha az görüşlü: Tek bir yöntemle sınırlı değilsiniz. Önerilen bir yaklaşım olsa da, bunu benimsemeniz gerekmez.

Zustand vs. Redux

Redux, React ile çalışan klasik bir durum yönetim kütüphanesidir ve en popüler durum yönetimi kütüphanesi olarak kabul edilir. Bu nedenle, mimari tasarımlarını karşılaştırmak bu makalenin uygun bir bileşenidir.

Redux Mimarisi

Redux Architecture

İlk olarak, yukarıdaki mimaride görüldüğü gibi ön uç kullanıcı arayüzüne sahipsiniz. Action creator’lar, her kullanıcı isteği için doğru eylemin tetiklenmesini sağlar. Bir eylemi, uygulamada ne olduğunu açıklayan bir olay olarak düşünebilirsiniz. Bir düğmeye tıklamak veya bir arama yapmak gibi. Dispatcher’lar, bu eylemleri mağazaya göndermede yardımcı olur. Daha sonra, reducer’lar durumu nasıl ele alacaklarına karar verir. Reducer işlevi, geçerli durum ve eylem nesnesini alarak durumu değiştirir. Gerekirse yeni durumu döndürür ve güncellenen durum değişiklikleri kullanıcı arayüzünde render edilir.

Zustand Mimarisi

Zustand Architecture

Burada da kullanıcı arayüzü bileşeniniz var. Bir değişiklik isteği geldiğinde, mağazaya yönlendirilir. Mağaza, durumun nasıl değişmesi gerektiğine karar verir. Mağaza yeni durumu döndürdüğünde, kullanıcı arayüzü güncellenen değişikliklerle render edilir. Burada herhangi bir action creator, dispatcher veya reducer göremezsiniz. Bunun yerine, Zustand, durum değişikliklerine abone olmanıza olanak tanıyan bir özellik sunar. Bu, kullanıcı arayüzünüzü verilerinizle senkronize tutmanıza yardımcı olur.

Daha basit ve hafif bir durum yönetimi çözümü arayan geliştiriciler için Zustand mükemmel bir seçenektir.

Zustand’ı ReactJS ile Nasıl Kullanılırız ?

Zustand kullanarak durumları nasıl yöneteceğinizi göstermek için bir React projesi oluşturalım. Bir kütüphane mağazası uygulaması düşünün, kitap ödünç alma ve geri verme işlemlerini takip eder. Adımlar aşağıda listelenmiştir.

Bir React Uygulaması Oluşturun

npx create-react-app project_name

Zustand Bağımlılığını Yükleyin

npm i zustand

Bir Store Oluşturalım

//bookStore.js
import { create } from "zustand";

const bookStore = (set, get) => ({
books: [],
noOfAvailable: 0,
noOfIssued: 0,
addBook: (book) => {
set((state) => ({
books: [...state.books, { ...book, status: "available" }],
noOfAvailable: state.noOfAvailable + 1,
}));
},
issueBook: (id) => {
const books = get().books;
const updatedBooks = books?.map((book) => {
if (book.id === id) {
return {
...book,
status: "issued",
};
} else {
return book;
}
});
set((state) => ({
books: updatedBooks,
noOfAvailable: state.noOfAvailable - 1,
noOfIssued: state.noOfIssued + 1,
}));
},
returnBook: (id) => {
const books = get().books;
const updatedBooks = books?.map((book) => {
if (book.id === id) {
return {
...book,
status: "available",
};
} else {
return book;
}
});
set((state) => ({
books: updatedBooks,
noOfAvailable: state.noOfAvailable + 1,
noOfIssued: state.noOfIssued - 1,
}));
},
reset: () => {
set({
books: [],
noOfAvailable: 0,
noOfIssued: 0,
});
},
});

const useBookStore = create(bookStore);

export default useBookStore;

Zustand mağazası bir hook’tur, bu yüzden useBookStore bileşen adıdır. create yöntemi store oluşturmak için kullanılır. Store, her bileşenin paylaştığı tek bilgi kaynağıdır. set fonksiyonu, bir değişken veya nesnenin durumunu değiştirmek için kullanılır. get fonksiyonu ise eylemler içinde duruma erişmek için kullanılır.

Kitap storenin durum nesnesi üç alana sahiptir: books, kitapların kimlik, ad ve yazar gibi ayrıntılarını içeren bir dizi içerir. noOfAvailable, kütüphanedeki toplam kitap sayısını saklar, noOfIssued ise kullanıcılara verilen toplam kitap sayısını saklar. Kitap store dört yöntem sunar: addBook işlevi, kitaplar dizisine yeni bir kitap ekler ve mevcut kitap sayısını artırır ve her yeni eklenen kitabın durumunu available olarak ayarlar. issueBook işlevi, kullanıcıya bir kitap ödünç verir. İlgili kitap artık issued durumunda olacaktır. Mevcut kitap sayısında bir azalma ve verilen kitap sayısında bir artış olacaktır. returnBook işlevi, ödünç alınan kitabı kütüphaneye geri vermek için kullanılır. Geri verilen kitabın durumu available olarak değişir ve verilen kitap sayısında bir azalma olurken mevcut kitap sayısında bir artış olur. Son olarak, reset yöntemi tüm durum alanlarını temizler.

Bileşeni Store ile Bağlama

//App.js

import { useEffect } from "react";
import BookForm from "./components/BookForm";
import BookList from "./components/BookList";
import useBookStore from "./bookStore";
import "./App.css";

function App() {
const reset = useBookStore((state) => state.reset);

useEffect(() => {
reset();
}, [reset]);

return (
<div className="App">
<h1>Library App</h1>
<BookForm />
<BookList />
</div>
);
}

export default App;

Uygulama başlatıldığında, kütüphanenin durumu sıfırlanır. reset işlevi durum değerlerini temizler. Kitap eklemek ve görüntülemek için BookForm ve BookList bileşenlerini içeren bir başlık render edilir.

Kitap Ekleme Formu

//components/BookForm.js

import { useState } from "react";
import useBookStore from "../bookStore";

const BookForm = () => {
const [book, setBook] = useState({ title: "", author: "" });
const addBook = useBookStore((state) => state.addBook);

const handleChange = (e) => {
const { name, value } = e.target;
setBook({ ...book, [name]: value });
};

const handleSubmit = (e) => {
e.preventDefault();
addBook({ ...book, id: Math.floor(Math.random() * 1000) });
setBook({ title: "", author: "" });
};

return (
<form onSubmit={handleSubmit}>
<input
type="text"
name="title"
placeholder="Enter book title"
value={book.title}
onChange={handleChange}
/>
<input
type="text"
name="author"
placeholder="Enter book author"
value={book.author}
onChange={handleChange}
/>
<button type="submit">Add Book</button>
</form>
);
};

export default BookForm;

Kitap Listesi

//components/BookList.js

import useBookStore from "../bookStore";

const BookList = () => {
const { books, issueBook, returnBook, noOfAvailable, noOfIssued } =
useBookStore();

return (
<div>
<h2>Total books: {books.length}</h2>
<h2>Available books: {noOfAvailable}</h2>
<h2>Issued books: {noOfIssued}</h2>
<ul>
{books.map((book) => (
<li key={book.id}>
<span>
{book.title} by {book.author} - {book.status}
</span>
{book.status === "available" ? (
<button onClick={() => issueBook(book.id)}>Issue</button>
) : (
<button onClick={() => returnBook(book.id)}>Return</button>
)}
</li>
))}
</ul>
</div>
);
};

export default BookList;

Uygulamayı başlatmak için npm start komutunu kullanın ve tarayıcınızda görüntüleyin. Kitap eklemek ve durumlarını yönetmek için bileşenlerle etkileşim kurabilirsiniz.

Zustand’ın hafif ve esnek yapısı sayesinde daha büyük uygulamalarda bile durum yönetimi daha kolay hale gelmektedir.Uygulamanızın karmaşıklığına ve ihtiyaçlarınıza göre Zustand’ı kolayca adapte edilebilmektedir.

Okuduğunuz için teşekkürler

Her zaman gelişmek için yer olduğunu anlıyorum. Lütfen düşüncelerinizi paylaşmaktan çekinmeyin.

--

--

Selim KURT

Software Developer - Mobile & Web Developer #react #reactnative #nextjs #frontend #digitaltransformation #javascript