-
-
Notifications
You must be signed in to change notification settings - Fork 118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Usage of cartCount causes an SSR mismatch error in Next.js #122
Comments
This sounds similar: https://dev.to/jaklaudiusz/next-js-persistent-state-with-react-hooks-and-localstorage-how-to-make-it-work-3al6 but not sure how we can bake that into the lib. |
I did some digging and traced it down to the |
There is a workaround: https://github.com/thorsten-stripe/next.js/commit/64ce389ed776e935584d35f9859a50f0f6b2c745 However the usage of |
So @thorsten-stripe the official way to fix it would be to modify |
Oh nvm looks like you're really on top of all this and you've already put out a PR for this. Much appreciated. |
@ChrisBrownie55 Yes, I believe that is the only way to avoid this discrepancy, however it's not great, because you have an initial render with the default state and then an immediate re-render with the localStorage state, which can result in a flicker when the page loads. One potential solution would be to initially return null until we had the chance to check the localStorage, that way you can employ conditional rendering to avoid the "flicker", but none of this feels great for non-SSR applications :( |
@thorsten-stripe it looks like this has been fixed here: soyguijarro/react-storage-hooks#8 You think you can try testing the upgraded version of |
Unfortunately it didn't fix the hydration warning issue, see soyguijarro/react-storage-hooks#18 (comment) |
So what I'm seeing here is that we need to display the default (a.k.a. empty) values for data stored in local storage and provide a status indicator for the data as well. I think this could look something like the following: export function useLocalStorageReducer(key, reducer, initialState) {
const [state, dispatch] = useReducer((state, action) => {
switch (action.type) {
case 'value updated':
return { status: 'loaded', value: action.storageValue }
case 'loading started':
return { status: 'loading', value: action.initialState }
default:
return state
}
})
const dummyStorage = {/* ... */}
const storageValue = useStorageReducer(/* same stuff but make initial state: */ null)
useEffect(() => {
if (storageValue === null)
dispatch({ type: 'loading started', initialState })
else
dispatch({ type: 'value updated', storageValue })
}, [initialState, storageValue])
} This would also make it so that when |
@thorsten-stripe was this taken care of? Do we need to update this lib? |
It looks like setting |
Fwiw I've been running into this whilst using material-ui badges too - things like {cartCount > 0 ?
<IconButton href="/cart">
<Badge badgeContent={cartCount || 0} color="secondary" suppressHydrationWarning>
<ShoppingCartOutlined />
</Badge>
</IconButton>
: <></>
} which not only triggers the hydration warning, but also a mismatched className on the Badge being invisible (server side) or not (client side). My only solution, for now, has been to go with the premise that the shopping cart interaction will be client-side only, and wrap any use of cartCount in |
I'd say that that's a fair assumption as all of the cart information has to be loaded from either LocalStorage or with // "hidden" would be like "display: none" or something
<IconButton href="/cart" className={cartCount > 0 ? '' : 'hidden'} suppressHydrationWarning>
<Badge badgeContent={cartCount || 0} color="secondary">
<ShoppingCartOutlined />
</Badge>
</IconButton> If you still have the same issue with Other than that, we're still just waiting on soyguijarro/react-storage-hooks#20 to be merged to definitively solve this issue. |
Don't think this is an issue anymore, let me know if I'm wrong tho |
I'm not sure why this is happening:
![image](https://user-images.githubusercontent.com/23213994/84516376-4e17a880-ad00-11ea-97a8-8e87ab51ce94.png)
cartCount
renders correctly in the<p>
tag but for setting the disabled value on the button it doesn't: https://github.com/thorsten-stripe/next.js/blob/thor/stripe/add-use-shopping-cart-example/examples/with-stripe-typescript/components/CartSummary.tsx#L45The text was updated successfully, but these errors were encountered: