React and easy-peasy - How to reset full state?

945 views Asked by At

I can't find a way to reset full state to a new one. As soon as I try one or the other approach, sometimes it seems to work (with smaller new state), but most of the time my components re-render (because of state change and I assume not yet rehydrated) and I get an error that something is not defined.

I've tried store.reconfigure(newStateModel), but I don't quite understand how it's supposed to work when it maintains the old state (it looks like it merges both old and new states). So I tried await store.persist.clear() before reconfiguring, but then again I get re-render error, that something is undefined.

I also found this thread on GitHub and tried both approaches:

setState: action((state, payload) => payload),

// and

reset: action((state, payload) => ({
  ...initialState,
}),

Still exact same issue (something is undefined on re-render)

Was thinking to somehow show "Loading..." view on main App component, but I don't use any state there (only store itself), so it doesn't even re-render. Currently my App is:

const WaitForStateRehydration = ({children}) => {
    return useStoreRehydrated() ? children : <Loader/>
}

export default ({store}) => {
    return (
        <StoreProvider store={store}>
            <WaitForStateRehydration>
                <FsContextProvider>
                    <Panel />
                </FsContextProvider>
            </WaitForStateRehydration>
        </StoreProvider>
    )
}

My FsContextProvider is a loader (with context), which loads after some data is available:

const FsContextProvider = ({children}) => {
    // ...

    return (
        <LoaderWrapper waitToLoad={someData}>
            <FsContext.Provider value={someData}>
                {children}
            </FsContext.Provider>
        </LoaderWrapper>
    )
}

I'm so lost here
Any help would be appreciated

2

There are 2 answers

0
Karmalakas On BEST ANSWER

Not sure if that's the way to go, but it seems to work for me.
I added a loading param and an action to my store model:

    loading: boolean
    setLoading: Action<StoreState, boolean>

Changed my reset action to reset everything but loading param.
Then in my <Panel /> I added a check:

const Panel = () => {
    const loading = useStoreState(state => state.loading)

    return (
        loading
            ? <Loader/>
            : (
                <>
                    // Other panel components
                </>
            )
    )
}

And finally where I need to reset the state, I did it like this:

store.dispatch.setLoading(true)
store.dispatch.reset(newState)
store.dispatch.setLoading(false)
0
Sanchitos On

I had my persist in localStorage and I needed to clear it.

await store.persist.clear() didn't worked for me.

What I did to resolve it is pretty hacky.

When creating the store:

const Store = createStore(persist(StoreModel, { storage: 'localStorage' }), {
  name: 'some_key'
});

This created a key in the localStorage with the name: '[some_key][0]'

Then I did this in the code where I need it to empty it:

localStorage.removeItem('[some_key][0]');

It ain't fancy but It gets the job done.