在我的反应应用程序中,我有3个组件。从第一个组件的按钮,我使用链接转到第二个组件。在第二个我创建一个状态(redux商店),操纵它,当操作完成后,通过提交按钮我重定向到第三个组件。在第3个组件中,我也看到了状态(通过redux chrome工具),但是当我刷新页面(更改和保存代码时的webpack事件)时,我失去了状态并获得了一个空对象。
这是我的应用程序的结构。
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;
在HomePage,我有一个链接到GameInit的按钮
const HomePage = () => (<Button color="blue" as={Link} to="/GameInit">START GAME</Button>);
export default HomePage;
和GameInit页面看起来像
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);
最后战斗组件,我第一次看到状态,但失去了刷新
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);
您可以轻松地将其保存在本地存储中。请查看以下示例。
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(
// Other reducer
persistedState,
);
render(
<Provider store={store}>
<App/>
</Provider>,
document.getElementById('root');
);
序列化是一项昂贵的操作。您应该使用节流功能(如lodash
实施的功能)来限制保存次数。
例如:
import throttle from 'lodash/throttle';
store.subscribe(throttle(() => {
saveState(store.getState());
}, 1000));
您可以使用类似redux-persist的东西将redux状态保存到local storage
或另一个存储系统。
我对热重新加载的个人建议是使用:React hot loader,这可以防止页面重新加载,只会切换更改的块。这意味着你的状态永远不会在失去时迷失。
它很容易安装。您只需添加一个条目并将您的初始组件包装在hot
中,您可以从包中获取该组件。
如果您需要有关其工作原理的更多信息,我建议您通过创建者观看this talk。