【问题标题】:Callbacks using redux-thunk / redux-observable with redux使用 redux-thunk / redux-observable 和 redux 的回调
【发布时间】:2018-03-19 10:31:08
【问题描述】:

我正在学习 redux 的工作原理,但它需要大量代码来做简单的事情。例如,我想在显示之前从服务器加载一些数据。出于编辑的原因,我不能简单地使用传入的道具,而是必须将道具数据复制到本地状态。

据我所知,我必须发送 Fetch_request 操作。如果成功,则 fetch_success 操作将使用新项目更新商店。然后更新的项目将导致我的组件的渲染功能更新。

在组件中

componentWillMount() {
  this.props.FETCH_REQUEST(this.props.match.params.id);
}
...

在行动中

export function FETCH_REQUEST(id) {
  api.get(...)
    .then(d => FETCH_SUCCESS(d))
    .catch(e => FETCH_FAILURE(e));
}
...

在减速器中

export function FETCH_REDUCER(state = {}, action ={}) {
  switch (action.type) {
    case 'FETCH_SUCCESS':
      return { ...state, [action.payload.id]: ...action.payload }
  ...
}

返回组件

this.props.FETCH_REDUCER
// extra code for state, getting desired item from...

相反,我可以调用 react-thunk 函数并传递一些回调函数吗? react-thunk 可以更新存储,回调可以改变组件的本地状态。

在组件中

componentWillMount() {
  this.props.FETCH_REQUEST(this.props.match.params.id, this.cbSuccess, this.cbFailure);
}
cbSuccess(data) {
  // do something
}
cbFailure(error) {
  // do something
}
...

在行动

export function FETCH_REQUEST(id, cbSuccess, cbFailure) {
  api.get(...)
    .then(d => {
      cbSuccess(d);
      FETCH_SUCCESS(d);
    }).catch(e => {
      cbFailure(d);
      FETCH_FAILURE(e);
    });
}
...

这是不恰当的吗?我可以用 redux-observable 做同样的事情吗?


更新 1

我几乎把所有东西都移到了 redux 商店,即使是为了编辑(即将this.setState 替换为this.props.setState)。它简化了状态管理。但是,每次任何输入的 onChange 触发时,都会弹出一个新状态。 有人可以确认这是否可以吗?我担心应用程序的内存管理,因为 redux 会为每个状态保存一个 ref。

【问题讨论】:

    标签: javascript reactjs redux redux-thunk redux-observable


    【解决方案1】:

    首先,您应该在componentDidMount 而不是componentWillMount 中调用您的API。更多信息请访问:what is right way to do API call in react js?

    当您使用 redux 存储时,您的组件使用 mapStateToProps 函数订阅状态更改,并使用通过 mapDispatchToProps 函数添加道具的操作更改状态(假设您在连接调用中使用这些函数) . 因此,您已经在使用您的道具订阅状态更改。使用回调类似于让回调告诉您组件由于其 props 的更改而已经知道的更改。并且 props 的变化会触发组件的重新渲染以显示新的状态。

    更新: 您提到的情况是,输入字段在每个字符更改时触发 onChange 事件,可能会导致对存储进行大量更新。正如我的 cmets 中提到的,您可以使用 _.debounce 之类的 api 来限制对存储的更新,以减少这种情况下的状态更改次数。有关处理此问题的更多信息,请访问Perform debounce in React.js

    在使用 Redux 时,内存管理问题在实际应用程序中是一个真正的问题。减少重复更新对状态的影响的方法是

    1. 规范化状态的形状:http://redux.js.org/docs/recipes/reducers/NormalizingStateShape.html
    2. 使用 Reselect (https://github.com/reactjs/reselect) 创建记忆选择器
    3. 遵循文章中提供的有关 Redux github 页面性能的建议 (https://github.com/reactjs/redux/blob/master/docs/faq/Performance.md)

    还请记住,虽然应该复制整个状态以防止变异,但只有更改的状态片段需要更新。例如,如果你的 state 持有 10 个对象,并且只有一个发生了变化,你需要更新 state 中新对象的引用,但剩下的 9 个未更改的对象仍然指向旧的引用和你的对象总数内存是 11 而不是 20(不包括包含的状态对象。)

    【讨论】:

    • 如果我想编辑从 FETCH_REDUCER 收到的数据,我输入的 onChange 是否必须为每个字符更改发送一个操作?由于克隆,这不会浪费内存吗?我的想法是将 FETCH_REDUCER 的数据复制到本地状态,在本地进行更改,然后发送操作以更新存储。
    • 我同意你的观点。并且公认的解决方法是使用像 _.debounce 这样的函数来限制从 onChange 函数对 api 的调用。类似于@julien 在stackoverflow.com/questions/23123138/…中的回答@
    猜你喜欢
    • 2018-07-08
    • 1970-01-01
    • 2020-07-12
    • 2017-02-04
    • 2017-09-16
    • 2018-11-10
    • 1970-01-01
    • 2016-06-12
    • 1970-01-01
    相关资源
    最近更新 更多