in my react app I have 3 components. from the 1st component by a button, I use Link to go to the 2nd component. at the 2nd I create a state (redux store), manipulate it and when manipulation is finished by submitting button I redirect to the 3rd component. at the 3rd component, I also see the state (by redux chrome tool) but here when I refresh the page (the webpack thing when a code is changed and saved), I lose the sate and get an empty Object.
this is the structure of my app.
index.js
const store = createStore(
rootReducer,
composeWithDevTools(applyMiddleware(thunk))
);
ReactDOM.render(
<BrowserRouter>
<Provider store={store}>
<Route component={App} />
</Provider>
</BrowserRouter>,
document.getElementById("root")
);
App.js
const App = ({ location }) => (
<Container>
<Route location={location} path="/" exact component={HomePage} />
<Route location={location} path="/GameInit" exact component={GameInit} />
<Route location={location} path="/Battle" exact component={Battle} />
</Container>
);
App.propTypes = {
location: PropTypes.shape({
pathname: PropTypes.string.isRequired
}).isRequired
};
export default App;
Here at HomePage, I have a button that links to GameInit
const HomePage = () => (<Button color="blue" as={Link} to="/GameInit">START GAME</Button>);
export default HomePage;
and the GameInit Page looks like
class GameInit extends Component {
componentWillMount() {
const { createNewPlayer} = this.props;
createNewPlayer();
}
/* state manipulation till it gets valid */
palyerIsReady()=>{ history.push("/Battle");}
export default connect(mapStateToProps,{ createNewPlayer})(GameInit);
and finally Battle component where I first see the state but lose on refresh
class Battle extends Component {
render() {return (/*some stuff*/);}}
Battle.propTypes = {
players: PropTypes.object.isRequired // eslint-disable-line
};
const mapStateToProps = state => ({
players: state.players
});
export default connect(mapStateToProps,null)(Battle);
You can easily persist it in the localstorage. Check the example below.
const loadState = () => {
try {
const serializedState = localStorage.getItem('state');
if(serializedState === null) {
return undefined;
}
return JSON.parse(serializedState);
} catch (e) {
return undefined;
}
};
const saveState = (state) => {
try {
const serializedState = JSON.stringify(state);
localStorage.setItem('state', serializedState);
} catch (e) {
// Ignore write errors;
}
};
const peristedState = loadState();
store.subscribe(() => {
saveState(store.getState());
});
const store = createStore(
persistedState,
// Others reducers...
);
render(
<Provider store={store}>
<App/>
</Provider>,
document.getElementById('root');
);
Serialization is an expensive operation. You should use a throttle function (like the one implemented by lodash
) to limit the number of saves.
Eg:
import throttle from 'lodash/throttle';
store.subscribe(throttle(() => {
saveState(store.getState());
}, 1000));
You can use something like redux-persist to save the redux state to local storage
or
to another storage system.
My personal advice for hot reloading is using this: React hot loader, this prevents page reload and only switch out the altered chunk. This implies that your state never gets lost while devving.
It is pretty easy to install. You only have to add an entry and wrap your initial component in hot
which you can get from the package.
If you need more information on how it works i suggest watching this talk by the creator.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With