UseEffect behavior between parent and children

37 Views Asked by At

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;
0

There are 0 best solutions below