I am using Zustand to manage my page navigation in a React app. The PageNav
component has the Next and Back buttons. My intention is to reset the page state on every load of a display
object's component, using the resetPageState
function. The issue is, if I put the reset function inside the Main
components's useEffect
, it does not reset correctly, meaning nav.isNextClicked
is always false and <NotEligible/>
never renders. However, if I put it in the UseEffect
of each display
component, it resets the page state properly. Which means that I have to repeat the useEffect
on all display
components. Is there a reason the Main
component's useEffect
is not catching up with the state correctly?
Here is the Main
component:
const Main = () => {
const nav = usePageControlStore();
const status = useEligibilityStore();
const display: Record<number, ReactElement> = {
1: <1 />,
2: <2 />,
3: <3 />,
4: <4 />,
5: <5 />,
};
// Set the page navigation state
useEffect(() => {
nav.resetPageState();
nav.setTotalPages(Object.keys(display).length);
return () => {
nav.setTotalPages(0);
};
}, [nav.page]);
if (!status.isEligible && nav.isNextClicked) {
return <NotEligible />;
}
return (
<Stack alignItems="center">
{display[nav.page]}
{nav.page === 1 ? (
<Button variant="contained" onClick={() => nav.nextPage()}>
Start
</Button>
) : (
<PageNav />
)}
</Stack>
);
};
export default Main;
Here is the Zustand store for page navigation:
import { create } from "zustand";
type PageControlStore = {
totalPages: number;
page: number;
isNextActive: boolean;
isNextClicked: boolean;
isBackActive: boolean;
isBackClicked: boolean;
resetPageState: () => void;
setTotalPages: (n: number) => void;
nextPage: () => void;
prevPage: () => void;
goTo: (n: number) => void;
};
export const usePageControlStore = create<PageControlStore>()((set) => ({
totalPages: 1,
page: 1,
isNextActive: true,
isNextClicked: false,
isBackActive: true,
isBackClicked: false,
resetPageState: () => set({ isNextClicked: false, isBackClicked: false }),
setTotalPages: (n) => set({ totalPages: n }),
nextPage: () =>
set((state) => ({
isNextClicked: true,
isBackClicked: false,
page: state.page >= state.totalPages ? state.page : state.page + 1,
})),
prevPage: () =>
set((state) => ({
IsNextClicked: false,
IsBackClicked: true,
page: state.page <= 1 ? state.page : state.page - 1,
})),
goTo: (n) =>
set((state) => ({
page: n >= 1 && n <= state.totalPages ? n : state.page,
})),
}));
And here is a display
component:
const One = () => {
const nav = usePageControlStore();
useEffect(() => {
nav.resetPageState();
}, []);
return (
<div>One</div>
);
};
export default One;