easy-peasy
easy-peasy copied to clipboard
Initial store data is components is always `null`, then loads + re-renders second time to a correct value automatically
This isn't the end of the world, as I can currently wrap every single component and every store value in an if check to see if the data has actually been loaded, but what seems to be happening is that all components mount and render twice -- once with an empty store and then one with the "real" value.
Has anyone seen/heard of this behavior before and have any idea what might be behind it/how to debug? Thank you =)

const Table = () => {
const db = useStoreState(state => state.db)
const tables = useStoreState(state => state.tables.entries)
const { name } = useParams()
console.log("[TABLE COMPONENT]")
console.log("DB:", db)
console.log("TABLES:", tables)
if (!tables || !db) return null
const table = tables.find(it => it.table_name == name)
const columns = table?.columns
.map(it => it.column_name)
.map(name => ({ Header: name, accessor: name }))
const req = useQuery(`/table/${name}`, () =>
db.selectRows(makeRowSelectArgs(table, { limit: 100 }))
)
switch (req.status) {
case "loading":
return <h1>Loading Tables...</h1>
case "error":
return <h1>Error fetching tables: {req.error.message}</h1>
case "success":
return <TableComp columns={columns} data={req.data} />
}
}
Without if (!tables || !db) return null (or equivalent on every component) this happens:

Okay it definitely has something do with rehydration and persistence to sessionStorage I'm using.
What I don't understand is why from this logging, the store shows as:
- Not rehydrated in
<Main>app root - Rehydrated in
<Main>, but not rehydrated and empty in<Home> - Still not rehydrated in
<Home>, but data is loaded now - Finally decides in
<Home>it's rehydrated as well at some point - 3 renders of
<Home>happen
If I go by just the rehydration state in <Main> it's still be empty + broken in other components :thinking:

const Main = () => {
const rehydrated = useStoreRehydrated()
console.log("REHYDRATED?", rehydrated)
if (!rehydrated) return <p>Loading...</p>
return (
<Router>
{/* snipped */}
</Router>
)
}
const App = () => {
return (
<div id="app">
<StoreProvider store={store}>
<Main />
</StoreProvider>
</div>
)
}
export default App
const Home = () => {
const hasura = useStoreState(state => state.hasura)
const tables = useStoreState(state => state.tables.entries)
const setTables = useStoreActions(actions => actions.tables.setEntries)
const rehydrated = useStoreRehydrated()
console.log("[HOME, index.tsx]")
console.log("REHYDRATED:", rehydrated)
console.log("HASURA:", hasura)
console.log("TABLES:", tables)
if (!rehydrated) return null
return (
<div class={style.home}>
{/* snipped */}
</div>
)
}```
Ignore the above, persist() doesn't seem to have an effect, result is still the same without it =/
@GavinRay97 sorry to hear that you are struggling with this. I have some much improved document improvements for the persist API. My initial thoughts when reading the above was that it was related.
Would you be able to create a small'ish reproducible example for me in CodeSandbox. It would really help me be able to debug this for you.
@ctrlplusb Hey, appreciate the response!
I found a workaround for this, which might also be useful in providing more info for the problem:
If I call useStore().getState() the value is always present/loaded/correct. So it seems to only happen with useStore() passing a selector function. And persistence doesn't impact it at all.
Will try to put up an example repro on Codesandbox this weekend :+1:
We are having a similar issue. When the size of the stored items increased above 5-6mb useStoreRehydrated this hook returns true before the actual rehydrate happens. We put a zero delayed setTimeout to partially fix the problem.
I've patched some significant bugs in v4. I have a very strong feeling it will address this issue. There were a few fundamental issues around the persisting and rehydration processes.
I'll let you know when the patches are released for test.
Great news! Thanks, mate
@aalpgiray would be great to see if the v4 release addresses this issue. 👍
We are on it. But of course, there are breaking changes. Hope we can do it soon. I'll let you know. Thanks again.
No stress. Sorry for any pain. 😅