Modern Web Uygulamalarında State Management Yaklaşımları
Modern web uygulamalarının karmaşıklığı arttıkça, state (durum) yönetimi giderek daha kritik bir konu haline geliyor. Bu yazıda, farklı state yönetim yaklaşımlarını, popüler kütüphaneleri ve best practice'leri inceleyeceğiz.
State Management Nedir ve Neden Önemlidir?
State management, web uygulamalarında veri akışını ve uygulama durumunu yönetme stratejisidir. İyi bir state yönetimi:
- Uygulamanın öngörülebilirliğini artırır
- Debugging sürecini kolaylaştırır
- Performansı optimize eder
- Kod bakımını kolaylaştırır
Modern State Management Yaklaşımları
1. Atomic State Management
Atomic state management, state'i en küçük parçalara bölerek yönetme yaklaşımıdır. Bu yaklaşım, gereksiz render'ları önler ve performansı artırır.
// Zustand ile atomic state örneği import create from 'zustand' interface CounterState { count: number increment: () => void decrement: () => void } const useCounterStore = create<CounterState>((set) => ({ count: 0, increment: () => set((state) => ({ count: state.count + 1 })), decrement: () => set((state) => ({ count: state.count - 1 })) })) // Kullanım function Counter() { const { count, increment } = useCounterStore() return ( <button onClick={increment}> Count: {count} </button> ) }
2. Server State Management
Modern uygulamalarda, sunucu state'i ile client state'i ayrı yönetmek önemlidir. React Query, SWR gibi kütüphaneler bu konuda özelleşmiş çözümler sunar.
// React Query örneği import { useQuery, useMutation } from '@tanstack/react-query' function TodoList() { const { data: todos, isLoading } = useQuery({ queryKey: ['todos'], queryFn: fetchTodos }) const mutation = useMutation({ mutationFn: addTodo, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['todos'] }) } }) if (isLoading) return 'Loading...' return ( <div> {todos.map(todo => ( <TodoItem key={todo.id} todo={todo} /> ))} <button onClick={() => mutation.mutate(newTodo)}> Add Todo </button> </div> ) }
3. Composable State Management
Vue ve React gibi modern framework'ler, composable/hooks pattern ile state yönetimini modüler hale getirmeyi sağlar.
// Vue Composition API ile state management import { ref, computed } from 'vue' export function useCart() { const items = ref([]) const total = computed(() => items.value.reduce((sum, item) => sum + item.price, 0) ) function addItem(item) { items.value.push(item) } function removeItem(id) { items.value = items.value.filter(item => item.id !== id) } return { items, total, addItem, removeItem } } // Kullanım export default { setup() { const { items, total, addItem } = useCart() return { items, total, addItem } } }
4. Proxy-Based State Management
Proxy'ler kullanılarak state değişimlerini otomatik olarak takip eden modern çözümler giderek yaygınlaşıyor.
// MobX örneği import { makeAutoObservable } from 'mobx' class TodoStore { todos = [] filter = 'all' constructor() { makeAutoObservable(this) } addTodo(text) { this.todos.push({ id: Date.now(), text, completed: false }) } toggleTodo(id) { const todo = this.todos.find(todo => todo.id === id) if (todo) { todo.completed = !todo.completed } } get filteredTodos() { switch (this.filter) { case 'completed': return this.todos.filter(todo => todo.completed) case 'active': return this.todos.filter(todo => !todo.completed) default: return this.todos } } }
State Management Best Practices
1. State Normalizasyonu
Karmaşık veri yapılarını normalize ederek yönetmek, performans ve bakım açısından önemlidir.
// Normalize edilmemiş veri const articles = [ { id: 1, title: 'Article 1', author: { id: 1, name: 'John' }, comments: [ { id: 1, text: 'Great article!', author: { id: 2, name: 'Jane' } } ] } ] // Normalize edilmiş veri const normalizedState = { articles: { byId: { 1: { id: 1, title: 'Article 1', authorId: 1, commentIds: [1] } }, allIds: [1] }, authors: { byId: { 1: { id: 1, name: 'John' }, 2: { id: 2, name: 'Jane' } }, allIds: [1, 2] }, comments: { byId: { 1: { id: 1, text: 'Great article!', authorId: 2 } }, allIds: [1] } }
2. State Segmentasyonu
State'i mantıksal bölümlere ayırmak, uygulamanın ölçeklenebilirliğini artırır.
// Pinia ile state segmentasyonu örneği import { defineStore } from 'pinia' // User store export const useUserStore = defineStore('user', { state: () => ({ user: null, preferences: {} }), actions: { async login(credentials) { // login logic } } }) // Cart store export const useCartStore = defineStore('cart', { state: () => ({ items: [], discounts: [] }), getters: { total: (state) => state.items.reduce((sum, item) => sum + item.price, 0) } }) // UI store export const useUIStore = defineStore('ui', { state: () => ({ theme: 'light', sidebar: false }) })
3. Performance Optimizasyonu
State değişikliklerinde gereksiz render'ları önlemek için memoization ve selector pattern'lerini kullanmak önemlidir.
// React + Redux ile selector örneği import { createSelector } from '@reduxjs/toolkit' const selectTodos = state => state.todos const selectFilter = state => state.filter const selectFilteredTodos = createSelector( [selectTodos, selectFilter], (todos, filter) => { switch (filter) { case 'completed': return todos.filter(todo => todo.completed) case 'active': return todos.filter(todo => !todo.completed) default: return todos } } )
Sonuç
Modern web uygulamalarında doğru state management stratejisi seçmek, uygulamanın başarısı için kritik öneme sahiptir. Önemli noktalar:
- Uygulamanın ihtiyaçlarına göre doğru yaklaşımı seçin
- State'i mantıksal parçalara bölün
- Performans optimizasyonlarını baştan planlayın
- Server state ve client state yönetimini ayırın
- Modern tooling ve pattern'lerden faydalanın
İlgili Etiketler: #StateManagement #Frontend #React #Vue #Redux #Zustand #Performance #WebDevelopment