React+Redux+Firebase刷新浏览器后数据丢失问题求助
嘿,我懂你碰到的这个麻烦了——Redux的store是存在浏览器内存里的,一旦刷新页面,整个store就会被重置回初始状态,所以你跳转后刷新,mapStateToProps里用find找对应的post自然就找不到,props里的posts就变成undefined了。咱们来看看怎么解决:
方案一:页面加载时重新拉取Firebase数据
最简单的办法就是在应用启动或者路由加载的时候,重新调用你已经写好的startSetPosts action,把Firebase的数据重新加载到Redux store里。
比如你可以在根组件(比如App.js)的componentDidMount生命周期里触发这个action:
import { connect } from 'react-redux'; import { startSetPosts } from '../actions/posts'; class App extends React.Component { componentDidMount() { this.props.startSetPosts(); } render() { return ( // 你的App内容 ); } } export default connect(null, { startSetPosts })(App);
这样每次页面刷新,App组件挂载时都会重新从Firebase拉取posts数据,Redux store里就有数据了,你的PostItemPage组件也能拿到对应的post了。
方案二:用Redux持久化持久化store数据(推荐)
如果不想每次刷新都去请求Firebase,你可以用redux-persist这个库,把Redux store里的posts数据存在localStorage里,刷新页面后自动恢复到store中。
步骤如下:
- 先安装依赖:
npm install redux-persist
- 修改你的store配置文件:
import { createStore, combineReducers, applyMiddleware, compose } from 'redux'; import thunk from 'redux-thunk'; import { persistStore, persistReducer } from 'redux-persist'; import storage from 'redux-persist/lib/storage'; // 默认用localStorage // 配置持久化规则,只持久化posts reducer的数据 const persistConfig = { key: 'root', storage, whitelist: ['posts'] }; const rootReducer = combineReducers({ filters: filtersReducer, questions: questionsReducer, posts: postsReducer }); // 生成持久化的reducer const persistedReducer = persistReducer(persistConfig, rootReducer); const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; export default () => { const store = createStore( persistedReducer, composeEnhancers(applyMiddleware(thunk)) ); const persistor = persistStore(store); return { store, persistor }; };
- 在你的根渲染文件(比如
index.js)里用PersistGate包裹App组件:
import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import { PersistGate } from 'redux-persist/integration/react'; import configureStore from './store/configureStore'; import App from './App'; const { store, persistor } = configureStore(); ReactDOM.render( <Provider store={store}> <PersistGate loading={<div>加载中...</div>} persistor={persistor}> <App /> </PersistGate> </Provider>, document.getElementById('root') );
这样你的posts数据就会被存在localStorage里,刷新页面后会自动加载回Redux store,不用每次都请求Firebase。
额外优化:处理加载状态
不管用哪种方案,都建议在PostItemPage组件里加个判断,避免数据还没加载完成时出现报错:
render() { if (!this.props.posts) { return <div>加载中...</div>; } return ( // 你的原有渲染内容 ); }
这样就能解决刷新页面后props数据变成undefined的问题啦!
内容的提问来源于stack exchange,提问作者Victor Garcia Civera
相关产品推荐
相关产品推荐

