introduce
State management is crucial to any React application, but traditional libraries like Redux can sometimes feel like overkill. Enter health statusa minimal yet powerful state management solution for React. In this article, we’ll take a deep dive into why Zustand is a developer favorite and how to start using it in your React projects.
What are conditions?
Zustand is React’s state management library, designed to be simple and intuitive. It’s lightweight and doesn’t require a lot of boilerplate, which makes it easier to use than Redux or even the React Context API. Let’s see how to use Zustand in a React application.
Setting up Zustand in React
-
Installation status
npm install zustand
-
Create store
Here is a simple example of how to set up a store in Zustand:import {create} from 'zustand'; const useStore = create((set) => ({ count: 0, increase: () => set((state) => ({ count: state.count + 1 })), decrease: () => set((state) => ({ count: state.count - 1 })), }));
-
Use Store in components
Now, let’s use the store in a React element:import React from 'react'; import { useStore } from './store'; const Counter = () => { const { count, increase, decrease } = useStore(); return ( <div> <h1>{count}</h1> <button onClick={increase}>Increase</button> <button onClick={decrease}>Decrease</button> </div> ); }; export default Counter;
Advanced Zustand functions: get, getState
- Zustand also provides two other useful functions: get and getState. These are used to retrieve the status and get the status at any point in time
Get status(): This function gives you the current state of your store without triggering a re-render.
import {create} from 'zustand';
const useStore = create((set) => ({
count: 0,
increase: () => set((state) => ({ count: state.count + 1 })),
decrease: () => set((state) => ({ count: state.count - 1 })),
}));
// Accessing the current state using getState()
const count= useStore.getState().count;
// Reading the current state value
console.log(count); // This will log the current count
// Modifying the state using the actions
store.increase(); // This will increase the count
console.log(store.count); // This will log the updated count
get(): This feature allows you to access status directly from the store itself. This is useful if you need to check or modify the status before or after setting it.
import {create} from 'zustand';
const useStore = create((set, get) => ({
count: 0,
increase: (amount) => {
const currentState = get(); // Access the current state using getState()
console.log("Current count:", currentState.count); // Log the current count
set((state) => ({ count: state.count + amount })); // Modify the state
},
}));
Slices in good condition
- As your application grows, it’s a good idea to organize your state into smaller, more manageable parts. This is where slicing comes into play. A slice is a modular state block with its own set of operations. Each slice can be defined in its own file, making your code cleaner and easier to maintain.
// counterStore.js
export const createCounterSlice = (set) => ({
count: 0,
increase: () => set((state) => ({ count: state.count + 1 })),
decrease: () => set((state) => ({ count: state.count - 1 })),
});
// userStore.js
export const createUserSlice = (set) => ({
user: { name: 'John Doe' },
setName: (name) => set({ user: { name } }),
});
// useBoundStore.js
import {create} from 'zustand';
import { createCounterSlice } from './counterStore';
import { createUserSlice } from './userStore';
export const useBoundStore = create((...a) => ({
...createCounterSlice(...a),
...createUserSlice(...a),
}));
How to use internal components
import { useBoundStore } from './useBoundStore'
const App = () => {
const { count, increase, decrease, user, setName } = useBoundStore();
}
persistent state in state
- Zustand’s persistence middleware will automatically store the state to localStorage when the state changes, and load it back when the page is reloaded, ensuring that the state remains unchanged without additional work.
import {create} from 'zustand';
import { persist } from 'zustand/middleware';
const useStore = create(
persist(
(set) => ({
count: 0,
increase: () => set((state) => ({ count: state.count + 1 })),
decrease: () => set((state) => ({ count: state.count - 1 })),
}),
{
name: 'counter-storage', // The name of the key in localStorage
}
)
);
Get data from API in Zustand
- To get data from the API in Zustand, create an operation in the store to handle the API call and update the status with the fetched data, load and error status.
import {create} from 'zustand';
const useStore = create((set) => ({
users: [], // Array to store fetched users
loading: false, // State to track loading status
error: null, // State to track any errors during API call
// Action to fetch users from the API
fetchUsers: async () => {
set({ loading: true, error: null }); // Set loading state to true and reset error
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
const data = await response.json();
set({ users: data, loading: false }); // Set users data and loading to false
} catch (error) {
set({ error: 'Failed to fetch users', loading: false }); // Set error if fetch fails
}
},
}));
export default useStore;