En este post vamos a ver como podemos setear un store
de zustand en un server page de NextJs y utilizarlo luego en cliente.
ยฟPor que querriamos hacer eso?
Pueden existir varios motivos, pero el principal es que supongamos que necesitamos setear el store con unos valores que recivimos de un terecero, como una llamada a una api.
Lo bueno de los server page es que podemos solicitar datos de forma asyncrona, pero si seteamos el store en un server page el store no existira en el cliente.
Creamos el store
Doy por echo en este post que sabes como instalar zustand y tienes conocimientos de nextjs.
store.ts
import {create} from 'zustand';
interface Store {
todos: Todo[];
addTodo: (text: string) => void;
toggleTodo: (id: number) => void;
}
export const useTodoStore = create<Store>((set) => ({
todos: [],
addTodo: (text) => set((state) => ({
todos: [...state.todos, { id: Date.now(), text, completed: false }]
})),
toggleTodo: (id) => set((state) => ({
todos: state.todos.map(todo =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
)
}))
}));
Iniciamos store en server page
Ahora en nuestro server page recuperamos los todos iniciales que queremos setear y hacemos un setState
:
import useTodoStore from './store';
export default async function Page() {
const response = await fetch('https://jsonplaceholder.typicode.com/todos');
if (!response.ok)
throw new Error('Network response was not ok');
useTodoStore.setState({
todos: response.json()
})
}
Sincronizar cliente con los datos que tenemos en el servidor
Ahora para este paso necesitamos crear un componenten de tipo cliente
el cual vamos a usar para inicializar el store y poder usarlo en el lado de el cliente.
StoreInitializer
'use client';
import {useRef} from "react";
import useTodoStore from "./store";
export default function StoreInitializer({todos}: {
todos: Todo[]
}) {
const initialized = useRef(false);
const store = useReservaStore();
if (!initialized.current) {
store.setState({ todos });
initialized.current = true;
}
return null;
}
En este punto ya tenemos los datos en el store y accesibles en el cliente y nos aseguramos de que cuando lo usemos en nuestra pagina cliente los datos ya este.
import useTodoStore from './store';
export default async function Page() {
const response = await fetch('https://jsonplaceholder.typicode.com/todos');
if (!response.ok)
throw new Error('Network response was not ok');
useTodoStore.setState({
todos: response.json()
})
}
return (
<>
<StoreInitializer todos={useTodoStore.getState().todos} />
<Todos />
</>
)
Links:
Top comments (0)