狀態管理是現代 Web 開發的重要方面,尤其是在複雜的應用程式中。它涉及處理可能隨時間變化的數據,並確保該數據在整個應用程式中一致表示。有效的狀態管理可以提高應用程式的可預測性和可維護性。
Zustand 是一個小型、快速且可擴展的 React 應用程式狀態管理解決方案。 Zustand 由 Jared Palmer 和 Daishi Kato 創建,提供了一個簡單直觀的 API,與其他解決方案相比,使狀態管理變得不那麼麻煩。
在深入了解 Zustand 之前,讓我們先了解一下 Web 應用程式中不同類型的狀態:
Zustand 擅長管理本地和全域狀態,並且可以與遠端狀態管理解決方案整合。
要開始使用 Zustand,先透過 npm、yarn 或 pnpm 安裝它:
npm install zustand # or yarn add zustand # or pnpm add zustand
Zustand 具有多項使其脫穎而出的功能:
讓我們來看看 Zustand 的基本實作:
import { create } from 'zustand' const useStore = create((set) => ({ bears: 0, increasePopulation: () => set((state) => ({ bears: state.bears + 1 })), removeAllBears: () => set({ bears: 0 }), })) function BearCounter() { const bears = useStore((state) => state.bears) return <h1>{bears} around here...</h1> } function Controls() { const increasePopulation = useStore((state) => state.increasePopulation) return <button onClick={increasePopulation}>one up</button> }
在此範例中,我們建立一個具有熊狀態的商店和兩個修改它的操作。然後,BearCounter 和 Controls 元件可以使用 useStore 鉤子存取和修改狀態。
讓我們將 Zustand 與其他流行的狀態管理解決方案進行比較:
Zustand 的優點:
缺點:
Zustand 的優點:
缺點:
Zustand 的優點:
缺點:
Zustand 的系統設計是基於幾個關鍵原則:
This design allows Zustand to be both simple and powerful, providing excellent performance even in large applications.
Zustand makes it easy to persist state, which is crucial for many applications. Here's an example using the persist middleware:
import { create } from 'zustand' import { persist } from 'zustand/middleware' const useStore = create(persist( (set, get) => ({ fishes: 0, addAFish: () => set({ fishes: get().fishes + 1 }), }), { name: 'food-storage', // unique name getStorage: () => localStorage, // (optional) by default, 'localStorage' is used } ))
This will automatically save the state to localStorage and rehydrate it when the app reloads.
One of Zustand's strengths is that it can be used outside of React components. This is particularly useful for integrating with other parts of your application or for testing:
const { getState, setState } = useStore // Getting state console.log(getState().bears) // Setting state setState({ bears: 10 }) // Using actions getState().increasePopulation()
Let's look at some real-world examples of using Zustand:
import { create } from 'zustand' const useAuthStore = create((set) => ({ user: null, isAuthenticated: false, login: (userData) => set({ user: userData, isAuthenticated: true }), logout: () => set({ user: null, isAuthenticated: false }), })) // Usage in a component function LoginButton() { const { isAuthenticated, login, logout } = useAuthStore() const handleAuth = () => { if (isAuthenticated) { logout() } else { // Simulate login login({ id: 1, name: 'John Doe' }) } } return ( <button onClick={handleAuth}> {isAuthenticated ? 'Logout' : 'Login'} </button> ) }
import { create } from 'zustand' const useCartStore = create((set) => ({ items: [], addItem: (item) => set((state) => ({ items: [...state.items, item] })), removeItem: (itemId) => set((state) => ({ items: state.items.filter((item) => item.id !== itemId), })), clearCart: () => set({ items: [] }), total: 0, updateTotal: () => set((state) => ({ total: state.items.reduce((sum, item) => sum + item.price, 0), })), })) // Usage in components function CartSummary() { const { items, total, removeItem } = useCartStore() return ( <div> {items.map((item) => ( <div key={item.id}> {item.name} - ${item.price} <button onClick={() => removeItem(item.id)}>Remove</button> </div> ))} <div>Total: ${total}</div> </div> ) }
import { create } from 'zustand' import { persist } from 'zustand/middleware' const useThemeStore = create(persist( (set) => ({ theme: 'light', toggleTheme: () => set((state) => ({ theme: state.theme === 'light' ? 'dark' : 'light', })), }), { name: 'theme-storage', } )) // Usage in a component function ThemeToggle() { const { theme, toggleTheme } = useThemeStore() return ( <button onClick={toggleTheme}> Switch to {theme === 'light' ? 'dark' : 'light'} mode </button> ) }
Zustand offers a refreshing approach to state management in React applications. Its simplicity, flexibility, and performance make it an excellent choice for both small and large projects. By reducing boilerplate and providing a straightforward API, Zustand allows developers to focus on building features rather than managing complex state logic.
While it may not have the extensive ecosystem of some older state management solutions, Zustand's design principles and ease of use make it a compelling option for modern React development. Its ability to work outside of React components and easy integration with persistence solutions further extend its utility.
For many React applications, Zustand strikes an excellent balance between simplicity and power, making it worth considering for your next project.
Zustand also handles asynchronous functions/code really well and without the need for any Middleware setup.
Let's talk a bit about that:
One of Zustand's strengths is its simplicity in handling asynchronous operations without the need for additional middleware or complex setups. This makes it particularly easy to work with API calls, data fetching, and other asynchronous tasks.
Zustand's approach to asynchronous code is straightforward:
Here's an example of how to implement asynchronous code in Zustand:
import { create } from 'zustand' const useUserStore = create((set) => ({ user: null, isLoading: false, error: null, fetchUser: async (userId) => { set({ isLoading: true, error: null }); try { const response = await fetch(`https://api.example.com/users/${userId}`); if (!response.ok) throw new Error('Failed to fetch user'); const userData = await response.json(); set({ user: userData, isLoading: false }); } catch (error) { set({ error: error.message, isLoading: false }); } }, })); // Usage in a component function UserProfile({ userId }) { const { user, isLoading, error, fetchUser } = useUserStore(); React.useEffect(() => { fetchUser(userId); }, [userId]); if (isLoading) return <div>Loading...</div>; if (error) return <div>Error: {error}</div>; if (!user) return null; return ( <div> <h1>{user.name}</h1> <p>Email: {user.email}</p> </div> ); }
In this example:
Unlike Redux, which often requires middleware like Redux Thunk or Redux Saga for handling async operations, Zustand's approach is much more straightforward. This simplicity can lead to less boilerplate and a gentler learning curve, especially for developers new to state management.
MobX and Recoil also offer ways to handle async operations, but Zustand's approach might be considered more intuitive due to its direct use of async/await syntax without additional abstractions.
Zustand 對非同步程式碼的處理體現了其簡單性和靈活性的理念。透過允許開發人員直接在儲存中編寫非同步函數,無需特殊語法或中間件,Zustand 可以輕鬆管理複雜的狀態操作,同時保持程式碼庫乾淨和可讀。
這種非同步程式碼方法,與 Zustand 的其他功能(如小套件大小和易於設定)相結合,使其成為各種規模的專案的絕佳選擇,特別是那些涉及重要非同步狀態管理的專案。
希望這個「有點指南」對任何正在思考如何管理全域應用程式狀態的人來說都是有用且富有洞察力的。
謝謝您,祝您編碼愉快。
看我的網站 https://www.ricardogesteves.com
跟著我@ricardogesteves
X(推特)
以上是Zustand,何時、如何以及為何的詳細內容。更多資訊請關注PHP中文網其他相關文章!