72
loading...
This website collects cookies to deliver better user experience
useState
hook and Window: storage event
features. import React from "react";
import ReactDOM from "react-dom";
import { Provider, connect } from "react-redux";
import { createStore } from "redux";
const Form = ({ name, handleChange }) => {
return (
<>
<input value={name} onChange={handleChange} />
</>
);
};
const reducer = (state, action) => {
switch (action.type) {
case "CHANGE":
return { ...state, name: action.payload };
default:
return state;
}
};
const store = createStore(reducer, { name: "" });
const mapStateToProps = (state) => {
return {
name: state.name,
};
};
const mapDispatchToProps = (dispatch) => {
return {
handleChange: (e) => dispatch({ type: "CHANGE", payload: e.target.value }),
};
};
const App = connect(mapStateToProps, mapDispatchToProps)(Form);
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
npm i redux-state-sync redux-persist
redux-state-sync
package defines it as:A lightweight middleware to sync your redux state across browser tabs. It will listen to the Broadcast Channel and dispatch exactly the same actions dispatched in other tabs to keep the redux state in sync.
import React from "react";
import ReactDOM from "react-dom";
import { Provider, connect } from "react-redux";
import { createStore, applyMiddleware } from "redux";
import {
createStateSyncMiddleware,
initMessageListener,
} from "redux-state-sync";
const Form = ({ name, handleChange }) => {
return (
<>
<input value={name} onChange={handleChange} />
</>
);
};
const reducer = (state, action) => {
switch (action.type) {
case "CHANGE":
return { ...state, name: action.payload };
default:
return state;
}
};
const store = createStore(
reducer,
{ name: "" },
applyMiddleware(createStateSyncMiddleware())
);
initMessageListener(store);
const mapStateToProps = (state) => {
return {
name: state.name,
};
};
const mapDispatchToProps = (dispatch) => {
return {
handleChange: (e) => dispatch({ type: "CHANGE", payload: e.target.value }),
};
};
const App = connect(mapStateToProps, mapDispatchToProps)(Form);
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
import {
createStateSyncMiddleware,
initMessageListener,
} from "redux-state-sync";
createStateSyncMiddleware
and initMessageListener
from redux-state-sync
package.const store = createStore(
reducer,
{ name: "" },
applyMiddleware(createStateSyncMiddleware())
);
initMessageListener(store);
applyMiddleware(createStateSyncMiddleware())
when created redux store and started the message listener initMessageListener(store);
.redux-persist
to persist and rehydrate our redux store. import React from "react";
import ReactDOM from "react-dom";
import { Provider, connect } from "react-redux";
import { createStore, applyMiddleware } from "redux";
import {
createStateSyncMiddleware,
initMessageListener,
} from "redux-state-sync";
import { persistStore, persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage";
import { PersistGate } from "redux-persist/integration/react";
const Form = ({ name, handleChange }) => {
return (
<>
<input value={name} onChange={handleChange} />
</>
);
};
const reducer = (state, action) => {
switch (action.type) {
case "CHANGE":
return { ...state, name: action.payload };
default:
return state;
}
};
const persistConfig = {
key: "root",
storage,
};
const persistedReducer = persistReducer(persistConfig, reducer);
const store = createStore(
persistedReducer,
{ name: "" },
applyMiddleware(
createStateSyncMiddleware({
blacklist: ["persist/PERSIST", "persist/REHYDRATE"],
})
)
);
initMessageListener(store);
const mapStateToProps = (state) => {
return {
name: state.name,
};
};
const mapDispatchToProps = (dispatch) => {
return {
handleChange: (e) => dispatch({ type: "CHANGE", payload: e.target.value }),
};
};
const App = connect(mapStateToProps, mapDispatchToProps)(Form);
const persistor = persistStore(store);
ReactDOM.render(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>,
document.getElementById("root")
);
import { persistStore, persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage";
import { PersistGate } from "redux-persist/integration/react";
persistStore
and persistReducer
: basic usage involves adding persistReducer and persistStore to our setup;storage
: in case of web app, defaults to localStorage;PersistGate
: In React usage, we'll wrap our root component with PersistGate. As stated in the docs: This delays the rendering of your app's UI until your persisted state has been retrieved and saved to redux.
const persistConfig = {
key: "root",
storage,
};
const persistedReducer = persistReducer(persistConfig, reducer);
const store = createStore(
persistedReducer,
{ name: "" },
applyMiddleware(
createStateSyncMiddleware({
blacklist: ["persist/PERSIST", "persist/REHYDRATE"],
})
)
);
createStore
, we replaced the old reducer
param by new customized reducer from package util persistedReducer
. We also need to blacklist some of the actions that is triggered by redux-persist, to State Sync middleware excludes them from syncronization.const persistor = persistStore(store);
ReactDOM.render(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>,
document.getElementById("root")
);
PersistGate
and pass persistor instance from persistStore
as props to component.