React Redux 刷新问题
Posted
技术标签:
【中文标题】React Redux 刷新问题【英文标题】:React Redux Refresh issue 【发布时间】:2017-02-21 17:43:42 【问题描述】:我正在使用 react-redux,但我遇到了刷新页面时我的 redux 状态丢失的问题。
在我继续之前,这是我可能搞砸的场景。
问题一:我可以连接到多个布局吗?
我有一个仪表板和一个“应用”布局。两者都有不同的布局。我以相同的方式连接两者:
import bindActionCreators from 'redux';
import connect from 'react-redux';
import * as actionCreators from '../actions/actionCreators';
function mapStateToProps(state)
return
profile: state.profile,
child: state.child,
function mapDispachToProps(dispatch)
return bindActionCreators(actionCreators, dispatch);
const LayoutApp = connect(mapStateToProps, mapDispachToProps) (DashboardLayout);
export default LayoutApp;
仪表板连接得很好。我可以在需要时点击减速器并更新商店,但是仪表板链接到应用程序以进行数据操作的某些部分供您使用。当它链接时,我按预期获取道具中的数据,但是一旦应用布局中的任何页面刷新,我就会丢失 maptoprops 发送的道具。
我尝试将其合并到一个主布局中,但这似乎具有相同的效果。当我第一次收到数据时,我也尝试立即保存状态,但刷新时它似乎也丢失了,这让我认为它正在重置它。
总结: - DashboardLayout(连接到redux) - AppLayout(连接到redux)但是在页面刷新后它会丢失Applayout的道具并且需要的数据消失了。
【问题讨论】:
该状态仅在您的初始页面加载的生命周期内存在。您可以使用redux-persist
保持状态并对其进行再水化。
请注意,@MarioTacke 提到的 redux-persist 只是您拥有的几十个选项之一。你可以将你的状态树持久化到服务器、本地存储、cookie,无论你想要什么(并且适合媒体)。重点仍然存在 - 默认情况下,状态树无法自行重新加载页面,它需要保存在某个地方。
为什么不在这两个布局之上的层次结构中创建一个状态呢?
为什么不在这两个布局之上的层次结构中创建一个状态呢?
How can I persist redux state tree on refresh?的可能重复
【参考方案1】:
了解 redux-persist
https://github.com/rt2zz/redux-persist
您可以使用安装它
npm i --save redux-persist
persistStore 是允许您持久存储的功能。
import persistStore from 'redux-persist'
而 autoRehydra 是在状态需要重新水化时执行的操作
import autoRehydrate from 'redux-persist'
以下是可能有用的结构。
import compose, applyMiddleware, createStore from 'redux'
import persistStore, autoRehydrate from 'redux-persist'
// add `autoRehydrate` as an enhancer to your store (note: `autoRehydrate` is not a middleware)
const store = createStore(
reducer,
undefined,
compose(
applyMiddleware(...),
autoRehydrate()
)
)
// begin periodically persisting the store
persistStore(store)
然后是你的减速器
import REHYDRATE from 'redux-persist/constants'
//...
case REHYDRATE:
var incoming = action.payload.myReducer
if (incoming) return ...state, ...incoming, specialKey:
processSpecial(incoming.specialKey)
return state
以下是可用于解决 redux-persist 的方法
persistor.pause() - pauses redux persist
persistor.resume() - resumes redux persist
persistor.purge() - deletes all persisted data
persistor.rehydrate() - calls reducer to rehydrate store
redux persist 允许的存储类型
// sessionStorage
import persistStore from 'redux-persist'
import asyncSessionStorage from 'redux-persist/storages'
persistStore(store, storage: asyncSessionStorage)
// react-native
import AsyncStorage from 'react-native'
persistStore(store, storage: AsyncStorage)
// web with recommended localForage
import localForage from 'localforage'
persistStore(store, storage: localForage)
这是redux-persist最基本的用法希望对你有帮助。
【讨论】:
【参考方案2】:您可以将任意数量的组件连接到相同的存储属性 - 这不是问题。需要注意的是,connect 正在侦听更改,因此当操作更改存储时,它会导致所有侦听更改存储部分的组件重新渲染(或至少进行计算然后比较 shadowdom)。
仅在运行应用程序时存储存储 - 在页面关闭/刷新后它被清除。
关于存储持久性(例如到本地存储)有一个很好的线程:Where to write to localStorage in a Redux app?
【讨论】:
【参考方案3】:正如前面的答案中提到的,将状态存储在本地存储中是一种可能的解决方案,但其他一些可能的解决方案是
确保您的链接使用 Push API 即 <Link to="route"/>
(react-router) 这将确保在路由更改之间不会删除存储
在创建商店时设置初始状态
const rootReducer = combineReducers(
todos: todos,
visibilityFilter: visibilityFilter
);
const initialState =
todos: [id:123, text:'hello', completed: false]
;
const store = createStore(
rootReducer,
initialState
);
这将在你的 reduce 存储初始化时为它补充水分
-
还有一些其他库/框架/样板,您可以使用它们也实现 服务器渲染 将在初始渲染时将 html 渲染到页面,然后在 DOM 加载一些内容后加载 React这个库是
Next.js,Electroide,react-redux-universal-hot-example
走这条路会大大增加您的应用程序的复杂性,因此您应该在走这条路之前权衡利弊
【讨论】:
【参考方案4】:我遇到了这个问题,所以正如这里有人提到的,我使用了 localStorage。
在我的减速器中,我这样做了:
const exampleKey = "_exampleKey"
const INITIAL_STATE =
example: JSON.parse(localStorage.getItem(exampleKey))
;
export default (state = INITIAL_STATE, action) =>
switch (action.type)
case 'SET_TRUE':
localStorage.setItem( exampleKey, JSON.stringify(true));
return ...state, example: true ;
case 'SET_FALSE':
localStorage.setItem( exampleKey, JSON.stringify(false));
return ...state, example: false;
default:
return state
将INITIAL_VALUES.example
指向localStorage 的项目example
确保我们在页面重新加载时保持正确的值。
希望它对某人有所帮助。
【讨论】:
以上是关于React Redux 刷新问题的主要内容,如果未能解决你的问题,请参考以下文章
React + redux + axios + thunk,等待interceptors.response 刷新token
使用 React Native 和 Redux 刷新 OAuth 令牌
如何使用 redux 模式在 react native 中刷新组件?