使用 React-ReactRouter-Redux 全家桶,需不需要手动清理 redux 的 state 数据呢?

2016-08-18 19:25:36 +08:00
 broadliyn

必入一个单页应用有许多的不同列表页,每个列表页都会有各自庞大的列表数据,而且数据也是经常会更新的。

面对这样的情况,切换不同的列表页时肯定是需要到服务器载入不同的列表数据的。如果一个用户连续点了不同的列表页,那么这些页面的数据都会保存到 redux state 里,即使切换 router 路径,数据依然会留着,很担心量大了以后会造成内存泄漏情况。

考虑过把所有列表的数据都存到同一个 state 里,切换列表自动替换上一个列表页的数据,但是如果是其他部分数据也很重,这种方法就无法使用适用了。因为每个页面 state 都不完全相同。

因此,对于这种情况,再每次切换 router 时候,需不需要手动清理一下当前路由的 state 呢?( 再或者一个多用户登陆的系统,用户1再进行了一些操作以后,退出登陆,这时候用户2登陆了,那么用户1的state数据肯定是要清除的。)

7563 次点击
所在节点    JavaScript
4 条回复
mdluo
2016-08-19 03:48:02 +08:00
Redux 的原则就是 state tree 以及用 reducer 来分拆各个部分,所以把所有的数据放到一个 reducer 来处理是不恰当的

可以在 reducer 里监听 LOCATION_CHANGE 这个 action ,每次路由发生变化就重置当前的数据,但是要注意哪怕是 URL 参数变化都会触发这个 action

另外一种方法是在资源的路由的主 Component 里的 componentWillUnmount 里 dispatch 一个自定义事件,对应的 reducer 里监听并重置状态

至于隔离不同的用户,那就在用户注销的地方 dispatch 一个 LOGOUT 的 action ,**每一个** reducer 里都监听它,并重置状态

import { LOCATION_CHANGE } from 'react-router-redux'
import * as types from 'constants/ActionTypes'

const initialState = {}

export default function reducer(state = initialState, action) {

switch (action.type) {

case types.LOGOUT:
case LOCATION_CHANGE:
return initialState

case types.SOME_ACTION:
return action.payload

default:
return state
}
}
broadliyn
2016-08-19 11:26:45 +08:00
@mdluo 非常感谢,有一定的了解了。
对于每一个不同的 view ,都需要从服务器取数据,在切换 location 的时候,这个到服务器取数据的动作应该在组件的哪个生命周期里触发呢(触发一个异步的 action 去取 http 数据)?
mdluo
2016-08-19 11:42:08 +08:00
@broadliyn componentWillMount 和 componentDidMount 里都可以, redux 的官方示例是在 componentWillMount 里发的

异步 action 需要用到 thunk Middleware ,或者做一个更高级的封装,比如: https://github.com/reactjs/redux/blob/master/examples/real-world/middleware/api.js
或者
https://github.com/agraboso/redux-api-middleware
broadliyn
2016-08-19 14:16:58 +08:00
@mdluo 非常感谢你的回复。目前在用 thunk middleware 。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/300257

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX