Open its-monotype opened 1 year ago
Will be fixed in #523 but will require some code changes.
I am having same issue but this happens when I run the query in getServerSideProps and then call the rtkQuery hook inside any component or page, then I get the above error.
But it appears just once and no more.
Plus I am trying to achieve this but it doesn't work, because I need the context in the axiosbaseQuery I created and calling the endpoint in the getInitialProps of the app is out of the provider
Just chiming in that this issue seems to occur when using RTK's dispatcher within a NextJS SSR block. I have a simple app skeleton that I am building out. It is using the SSR block to set the nav links into the state depending on the URL parameters. There is nowhere in the app's components where the store is changed other than with an onClick
handler.
When I transition from the first page to the next this warning appears. The only way I can make it go away is by removing any references to the state selector for example, the NavLinks
component which is using useAppSelect
to get the nav links from my state/store.
Example SSR Block:
export const getServerSideProps = wrapper.getServerSideProps(
(store) => async () => {
// Set the nav first so we can access on the 404 page
store.dispatch(
setNavigation({
isRestaurant: false,
navLinks: genericNavLinks.links,
isOpen: false,
})
);
// Check we have page data
const pageData = pages.find((page) => page.slug === "/");
if (!pageData) return { notFound: true };
return { props: { ...pageData } };
}
);
The NavDrawer component (has the dispatch):
const NavDrawer: React.FC<NavDrawerProps> = ({ testId, id, style }) => {
const { isOpen } = useAppSelector(selectNavigation);
const dispatch = useAppDispatch();
const handleNavClose: React.MouseEventHandler<HTMLButtonElement> = () =>
dispatch(setNavigationOpen(false));
return isOpen ? (
<>
<Underlay onClick={handleNavClose} isActive={true} />
<div
data-testid={testId}
style={style}
className={styles.wrapper}
id={id}
>
<NavDrawerHeader />
<NavLinks />
<NavDrawerFooter />
</div>
</>
) : (
<MobileNavOpenButton />
);
};
The NavLinks component (If I remove the selector from here the warning goes away):
const NavLinks: React.FC<NavLinksProps> = ({ testId, id }) => {
const { navLinks } = useAppSelector(selectNavigation);
return (
<div className={styles.wrapper}>
<ul role="list" data-testid={testId} className={styles.list} id={id}>
{navLinks.map((link) => (
<NavLink key={link.id} link={link} />
))}
</ul>
</div>
);
};
This has been doing my head in for a few days now, any advice?
Ok, so I have managed to find a solution in my specific situation. I think this is something which will be fixed in https://github.com/kirill-konshin/next-redux-wrapper/pull/523 if I read both the issue and the solution properly.
In my case it seemed to be the case that the <NavDrawer />
component, and its children, were still rendering at the point the SSR block was dispatching its update to the store.
This meant that the isOpen
value was true
and an open nav drawer was rendering. Then the isOpen
value was changed to false
(via the SSR block) before it finished. This would stand to reason with the information in the error and why it only happened on the first transition.
From what I am making of it, the issue was: Initial state (isOpen: false
) > SSR dispatch (isOpen: false
) > Nav Drawer opened (isOpen: true
) > Click Anchor (isOpen: true
) > Trigger hydration (isOpen: true
) > Hydration changes state (isOpen: false
) > Component is stale (isOpen: true
) > Re-render DOM with new state (isOpen: false
) > Initial state not set again
For me to solve this I altered my <AnchorLink/>
component to take an option callback and placed the dispatch
in there. This has removed the error entirely, presumingly because the state is updated before the transition to a new page begins, thus has time to complete before hitting the SSR block.
If anyone else has a better idea of why this approach worked I would definitely love to hear :)
EDIT:
Adding on to this it seems that allowing the hydrate
block to change the actual nav links which are rendered will cause this issue to persist. I presume the issue is stemming from the fact that the array of nav links has been changed into a proxied array which has also proxied each of the objects within it?
// No issue
builder.addCase(hydrate, (state, action) => {
state.isOpen = action.payload.navigation.isOpen;
state.isRestaurant = action.payload.navigation.isRestaurant;
state.restaurant = action.payload.navigation.restaurant;
return state;
});
// Issue
builder.addCase(hydrate, (state, action) => {
state.isOpen = action.payload.navigation.isOpen;
state.isRestaurant = action.payload.navigation.isRestaurant;
state.restaurant = action.payload.navigation.restaurant;
// Problematic line
state.navLinks = action.payload.navigation.navLinks;
return state;
});
EDIT 2:
The solution above is not a solution (whoops) turns out that by not including the links in the hydration update the menu is not updated when it should be and the first set of links the user acquires is the only one they will ever see :/
EDIT 3:
Sorry for all the spam. Just want to chime in that upgrading to the latest pre release branch has removed the issue for me while allowing the nav links to be updated on the hydration action
When I implemented the logic of fetching the authenticated user and setting it to the Redux state inside the
App.getInitialProps
method and accessing that user from the state within any Next.js page, I encountered an error when navigating between pages.Here is the problem. Inside
App.getInitialProps
I'm fetching the API endpoint using RTK Query to retrieve the auth user from the cookie and when the query is fulfilled user adds to the state. And that causes that error in the console.The query that I initiate inside App.getInitialProps: