Skip to content

Commit

Permalink
Implement RehydrateGate example component.
Browse files Browse the repository at this point in the history
  • Loading branch information
zewish committed Nov 16, 2024
1 parent e43106d commit eb27839
Show file tree
Hide file tree
Showing 19 changed files with 900 additions and 4,925 deletions.
31 changes: 7 additions & 24 deletions LEGACY-USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,48 +113,31 @@ Legacy usage - inside a reducer
-------------------------------

```js
import { SOME_ACTION } from './actions';
import { REMEMBER_REHYDRATED, REMEMBER_PERSISTED } from 'redux-remember';

const defaultState = {
changeMe: null,
rehydrated: false,
persisted: false
isRehydrated: false,
isPersisted: false
};

const changeMeReducer = (state = defaultState, action) => {
const reduxRemember = (state = defaultState, action) => {
switch (action.type) {
case REMEMBER_REHYDRATED:
// state gets rehydrated from storage
// payload is Rehydrated Root State
// "action.payload" is the Rehydrated Root State
return {
...changeMe: action.payload.changeMeReducer?.changeMe || null,
rehydrated: true
isRehydrated: true
};

case REMEMBER_PERSISTED:
return {
...state,
rehydrated: false,
persisted: true
};

case SOME_ACTION:
// example: only merge payload from SOME_ACTION event types
// after the state rehydration is done
if (!state.rehydrated) {
return state;
}

return {
...state,
changeMe: action.payload
isPersisted: true
};

default:
return state;
}
}

export default changeMeReducer;
export default reduxRemember;
```
75 changes: 45 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,48 +157,31 @@ Usage - inside a reducer
import { createSlice, createAction, PayloadAction } from '@reduxjs/toolkit';
import { REMEMBER_REHYDRATED, REMEMBER_PERSISTED } from 'redux-remember';

type InitialState = {
changeMe: any;
rehydrated: boolean;
persisted: boolean;
const initialState = {
isRehydrated: false,
isPersisted: false
};

const initialState: InitialState = {
changeMe: null,
rehydrated: false,
persisted: false
};

const myReducer = createSlice({
name: 'my-reducer',
const reduxRemember = createSlice({
name: 'redux-remember',
initialState,
reducers: {
someAction(state, action: PayloadAction<{ changeMe: any }>) {
if (!state.rehydrated) {
return;
}

state.changeMe = action.payload.changeMe;
}
},
reducers: {},
extraReducers: (builder) => builder
.addCase(createAction<{ myReducer?: InitialState }>(REMEMBER_REHYDRATED), (state, action) => {
// @INFO: action.payload.myReducer => rehydrated state of this reducer or "undefined" during the first run
state.changeMe = action.payload.myReducer?.changeMe || null;
state.rehydrated = true;
.addCase(createAction(REMEMBER_REHYDRATED), (state, action) => {
// "action.payload" is the Rehydrated Root State
state.isRehydrated = true;
})
.addCase(createAction<{ myReducer?: InitialState }>(REMEMBER_PERSISTED), (state, action) => {
// @INFO: action.payload.myReducer => persisted state of this reducer or "undefined" in case this reducer is not persisted
state.rehydrated = false;
state.persisted = true;
.addCase(createAction(REMEMBER_PERSISTED), (state, action) => {
state.isPersisted = true;
})
});

const reducers = {
myReducer: myReducer.reducer,
reduxRemember: reduxRemember.reducer,
// ...
};

const rememberedKeys = [ 'myStateIsRemembered' ];
const reducer = rememberReducer(reducers);
const store = configureStore({
reducer,
Expand All @@ -210,9 +193,41 @@ const store = configureStore({
)
});

export type RootState = ReturnType<typeof store.getState>;
export default store;

// Continue using the redux store as usual...
```

Usage - React rehydration gate (to be used with: [Usage - inside a reducer](#usage---inside-a-reducer))
-------------------------------------------------------------------------------------------------------

```tsx
import { FC, PropsWithChildren } from 'react';
import { useSelector } from 'react-redux';
import ReactDOM from 'react-dom/client';
import store, { RootState } from './store';

const RehydrateGate: FC<PropsWithChildren> = ({ children }) => {
const isRehydrated = useSelector<RootState>((state) => state.reduxRemember.isRehyrdated);
return isRehydrated
? children
: <div>Rehydrating, please wait...</div>;
};

const root = ReactDOM.createRoot(
document.getElementById('root')!
);

root.render(
<Provider store={store}>
<RehydrateGate>
<App />
</RehydrateGate>
</Provider>
);
```

Usage - legacy apps (without redux toolkit)
-------------------------------------------

Expand Down
21 changes: 0 additions & 21 deletions demo-web/.babelrc.mjs

This file was deleted.

2 changes: 1 addition & 1 deletion demo-web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
font-size: 2rem;
}

p {
p, .description {
margin: 1rem 0 0 0;
}

Expand Down
Loading

0 comments on commit eb27839

Please sign in to comment.