【问题标题】:React/Redux, implementing multiple actions with Redux ThunkReact/Redux,使用 Redux Thunk 实现多个操作
【发布时间】:2016-08-06 19:56:49
【问题描述】:

我正在学习 react/redux,并且有一个包含两个主要状态的应用程序:

  1. 一组项目
  2. 包含用户为这些项目指定的过滤器的对象

我有三个函数/操作,createFilterupdateFilterdeleteFilter,它们可以修改 #2 的状态。我有一个动作filterItems,它根据#2 的状态修改#1。因此,每当 #2 发生变化时,都需要调度此操作。

这是我正在使用的组件:

import React, { Component } from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'

import { createFilter } from '../actions/actions'
import { updateFilter } from '../actions/actions'
import { deleteFilter } from '../actions/actions'
import { filterItems } from '../actions/actions'

class ItemList extends Component {

 createFilter(input) {
       this.props.createFilter(input)
       this.props.filterItems()
    }

    updateFilter(input) {
       this.props.updateFilter(input)
       this.props.filterItems()
    }

    deleteFilter() {
       this.props.deleteFilter()
       this.props.filterItems()
    }

    ...
    // Render method
    ...
}

function mapDispatchToProps(dispatch) {
    return bindActionCreators({ createFilter, updateFilter, deleteFilter, filterItems }, dispatch)
}

function mapStateToProps({ itemList }) {
    return { itemList }
}

export default connect(mapStateToProps, mapDispatchToProps)(ItemList)

我发现,当发送过滤器方法之一时,在调用filterItems() 时,存储(状态#2)尚未更新。

所以我需要异步执行过滤功能,一旦更新存储调用filterItems

我正在努力解决如何使用react-thunk 做到这一点。如果第一个函数是 ajax 承诺,我会使用 .then():

export function updateFilterAndEvaluate(input) {
    return (dispatch, getState) => {
        updateFilter(input).then(dispatch(filterItems(getState().filters)))
    }
}

但这些只是函数,并没有 .then() 方法。我正在试图弄清楚我对这个实施的最佳行动方案是什么。我可以将 Redux 操作包装在一个 Promise 中吗?我在滥用 Thunk 吗?还是我应该尝试完全不同的模式?

【问题讨论】:

  • 为什么updateFilter 不返回一个承诺?

标签: javascript reactjs redux redux-thunk


【解决方案1】:

我有一个动作 filterItems 根据 #2 的状态修改 #1。

一般来说,这是一种反模式。由于结果数组可以从源数组和当前活动的过滤器中计算,因此您不应将其保持在状态。

Redux 操作通常应该看起来像“事件”(例如发生了什么)。 “过滤器已创建”和“过滤器已更新”是很好的操作。 “现在过滤它们!”看起来更像是一个命令,这通常表明它本来就不应该是一个动作,而应该是组件在选择要呈现的数据时所做的事情。

当您为组件准备数据时,将过滤作为mapStateToProps() 函数的一部分进行。如果它变得昂贵,look into using Reselect to compute derived data efficiently

至于你的具体问题,

我发现,当发送过滤器方法之一时,在调用 filterItems() 时,存储(状态 #2)尚未更新。

这是不正确的,表明您的代码中存在其他问题。 (很难说在哪里,因为这个例子不完整)。在 Redux 中,dispatch() 是同步的(除非你有一些中间件会延迟或批处理它,通常情况并非如此),所以如果它只是对本地数据进行操作,你不需要“等待”它完成.

但是,无论如何,filterItems() 不太适合某个动作,我建议您按照我在上面写的那样研究mapStateToProps() 中的过滤。

【讨论】:

  • 太棒了,谢谢!这是有道理的。通过在组件的 mapStateToProps 方法中进行过滤,我得到了它的工作版本。作为一个后续问题,如果项目通过过滤器时它们被过滤器修改了怎么办?然后他们需要在一个动作中被分派来更新 store 的新修改状态是否正确?
  • 为什么过滤器会修改项目?我不明白用例。如果他们只是“格式化”一些在应用过滤器时临时改变的东西,我希望mapStateToProps 复制它需要修改的任何内容,并将其作为道具传递下去。 mapStateToProps 永远不能 dispatch action,它应该是一个纯函数。
  • 我只是在试验,但用例是在项目中存储过滤器的标识符,这样,如果要再次过滤该项目,它可以绕过过滤器逻辑并获得批准。我也可以在组件内部移动过滤器。
  • 为什么需要绕过逻辑?如果您担心性能,请参阅我的回答中的第三段:“如果它变得昂贵,请考虑使用 Reselect 来有效地计算派生数据。” Redux 文档有一个page dedicated to this exclusively
猜你喜欢
  • 2018-03-20
  • 2018-01-31
  • 2019-01-24
  • 2019-02-02
  • 2018-09-22
  • 1970-01-01
  • 2019-03-23
  • 1970-01-01
  • 2016-11-19
相关资源
最近更新 更多