Managing state efficiently in a Next.js App Router environment can be challenging, especially when dealing with Server Components and Client Components. This is where next-state-adapter comes into play—providing a seamless solution for managing state across your Next.js application.
🚀 Why next-state-adapter?
next-state-adapter is a state management adapter specifically designed for Next.js App Router. It offers:
-
Seamless integration with Next.js (
app/
directory) - Efficient server-side data handling for initial state hydration
- Simplified state hydration in Client Components
- Support for class components with an easy-to-use Higher-Order Component (HOC)
- Works with various state management libraries like Mobx, Zustand, Jotai, Recoil, and others, giving you the flexibility to use your preferred state manager.
📦 Getting Started
First, install the package using npm or yarn:
npm install next-state-adapter
# or
yarn add next-state-adapter
🛠 Setting Up next-state-adapter
1. Create the Root Store and Provider
Start by setting up the root store and necessary hooks for state management:
// ~/store/config.ts
'use client';
import {RootStore} from "@/store/root";
import {createProvider, useStore} from "next-state-adapter";
const makeStore = () => new RootStore();
export const useAppStore = useStore.withTypes<RootStore>();
export const useAppStoreHydration = useStoreHydration.withTypes<RootStore>();
export const StoreProvider = createProvider(makeStore);
// ~/store/withStore.ts
import {withStore as withStoreHoc} from "next-state-adapter";
export const withStore = withStoreHoc.withTypes<RootStore>();
2. Wrap Your Application with the Store Provider
Now, wrap your application in the StoreProvider
component inside layout.tsx
:
// ~/app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<StoreProvider>
{children}
</StoreProvider>
</body>
</html>
);
}
3. Use the Store in a Client Component
Let’s create a Todo List component that fetches initial data from the server and hydrates the client-side store:
// ~/todos/list.tsx
'use client';
const TodoList = ({ initialTodos }: { initialTodos: Todo[] }) => {
const { todos } = useAppStoreHydration((store) => {
store.todos.init(initialTodos);
});
return (
<ul>
{todos.todos.map((todo) => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
);
};
4. Use the Component in a Server Component
Now, fetch the initial state on the server and pass it to TodoList
:
// ~/app/todos/page.tsx
export default async function Todos() {
const initialTodos = await fetchTodos(); // Fetching initial data on server side
return <TodoList initialTodos={initialTodos} />;
}
5. Support for Class Components
If you're using class components, next-state-adapter
provides an easy way to inject the store via HOC:
type Props = {
store: RootStore;
initialUsers: User[];
};
class Users extends Component<Props> {
render() {
const { store } = this.props;
const users = store.users.users;
return (
<div>
{users.map((user) => (
<div key={user.id}>{user.id}</div>
))}
</div>
);
}
}
// Inject store and hydrate with initialUsers
typescript
export const UsersList = withStore(Users, (store, props) => {
store.users.init(props.initialUsers);
});
// Use in a server component
export default async function UsersPage() {
const initialUsers = await fetchUsers();
return <UsersList initialUsers={initialUsers} />;
}
🎯 Final Thoughts
The next-state-adapter simplifies state management in Next.js App Router applications by providing a structured, optimized. Whether you are working with functional components, class components, or server-side data hydration, this adapter ensures a smooth developer experience.
It also supports a wide range of state management libraries like Mobx, Zustand, Jotai, Recoil, and others, so you can integrate it with your preferred solution effortlessly.
Give it a try in your Next.js App Router project and experience a more efficient way to manage state!
🚀 Check out the official documentation: next-state-adapter docs
Top comments (2)
cool :)
Informative and straight to the point