Skip to content

Commit

Permalink
docs(blog): update zustand post (#6215)
Browse files Browse the repository at this point in the history
  • Loading branch information
necatiozmen authored Aug 2, 2024
1 parent a2b2c28 commit 029cc80
Showing 1 changed file with 113 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ description: We'll learn how to use Zustand in our React project.
slug: zustand-react-state
authors: chidume_nnamdi
tags: [dev-tools, react]
image: https://refine.ams3.cdn.digitaloceanspaces.com/blog/2023-05-18-zustand/social.png
image: https://refine.ams3.cdn.digitaloceanspaces.com/blog/2023-05-18-zustand/social-3.png
hide_table_of_contents: false
---

**This article was last updated on July 31, 2024, to add sections for Advanced State Management Techniques and Custom Hooks for Zustand.**

## Introduction

Redux changed the game in the global management system. It was so successful that it was widely adopted and used as the ideal state management system in any framework. Not only in the framework but its principle still serves greatly in software development. Almost all developers have used Redux to manage their global state, and we can all attest to how powerful, fast, and maintainable it is to use Redux as the global state management tool. It makes debugging very easy and our app is predictable.
Expand All @@ -22,6 +24,8 @@ Steps we'll cover:
- [What is Zustand?](#what-is-zustand)
- [Getting started with Zustand](#getting-started-with-zustand)
- [Build a To-do app using Zustand](#build-a-to-do-app-using-zustand)
- [Managing State Structures](#managing-state-structures)
- [Writing Custom Hooks](#writing-custom-hooks)

## What is Zustand?

Expand Down Expand Up @@ -425,12 +429,114 @@ const App = () => {
export default App;
```

<br/>
<div>
<a href="https://discord.gg/refine">
<img src="https://refine.ams3.cdn.digitaloceanspaces.com/website/static/img/discord_big_blue.png" alt="discord banner" />
</a>
</div>
## Managing State Structures

I was very eager to present advanced patterns of state management with Zustand, which I've come to investigate recently. These will help us deal with more complex state structures and improve application performance and maintainability.

Zustand helps us create nested state slices, so handling complex state structures is straightforward. Structuring the state in a more modular way makes it easier to update and manage some specific bits of state without impacting others.

Here is an example:

```javascript
const useStore = create((set) => ({
user: {
name: "",
age: 0,
address: {
street: "",
city: "",
},
},
updateUser: (newUser) =>
set((state) => ({ user: { ...state.user, ...newUser } })),
updateAddress: (newAddress) =>
set((state) => ({
user: {
...state.user,
address: { ...state.user.address, ...newAddress },
},
})),
}));
```

In this case, we had a nested state for the user and address, and therefore separate methods to update the fields of the user and address, respectively.

### Use Middleware with Zustand

Zustand can be enhanced with middleware to provide additional functionality, such as changes in state logging, the ability to save and load states in local storage, and handling asynchronous actions.

Below is how we may use middleware to log state changes:

```javascript
import { create } from "zustand";
import { devtools } from "zustand/middleware";

const useStore = create(
devtools((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
})),
);
```

Wrapping our store definition with the `devtools` configuration now allows state changes to be observable in the Redux DevTools extension, which is a great tool for debugging.

## Writing Custom Hooks

We'll see how to create custom hooks and utilities that would make state management easy with Zustand. They help in the reuse of logic for cleaner code in our React projects.

Custom hooks can encapsulate Zustand state logic, making it a lot easier to reuse and manage complex state interactions. Here's an example of how one can do that for managing user authentication state:

```javascript
import { create } from "zustand";

const useAuthStore = create((set) => ({
user: null,
login: (userData) => set({ user: userData }),
logout: () => set({ user: null }),
}));

const useAuth = () => {
const { user, login, logout } = useAuthStore();
return { user, login, logout };
};

export default useAuth;
```

With this custom hook, you may use it to manage the authentication state in any component by just calling `useAuth`.

### Constructing Utility Functions

Utility functions can also be used to simplify the state update and make code readability much easier. Below, take a look at an example with an updated nested state:

```javascript
const updateNestedState = (set, keyPath, value) => {
set((state) => {
const keys = keyPath.split(".");
let nestedState = state;
keys.slice(0, -1).forEach((key) => {
nestedState = nestedState[key];
});
nestedState[keys[keys.length - 1]] = value;
return { ...state };
});
};

const useNestedStateStore = create((set) => ({
data: {
user: {
profile: {
name: "",
},
},
},
updateProfileName: (name) =>
updateNestedState(set, "data.user.profile.name", name),
}));
```

That makes our task easier in updating state properties that are deeply nested and allows the use of the utility function in various parts of our application.

## Conclusion

Expand Down

0 comments on commit 029cc80

Please sign in to comment.