React / Redux,使用Redux Thunk实现多个操作

时间:2016-04-15 02:02:32

标签: javascript reactjs redux redux-thunk

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

  1. 项目数组
  2. 包含这些项目的用户指定过滤器的对象
  3. 我有三个功能/操作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)
    

    我发现,当发送其中一个过滤方法时,商店(状态#2)在调用filterItems()时尚未更新。

    所以我需要异步执行过滤功能,一旦商店更新,请致电filterItems

    我正在努力解决如何使用react-thunk执行此操作。如果第一个函数是ajax承诺,我会使用.then()

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

    但这些只是函数,并没有.then()方法。我想弄清楚我的最佳行动方案是什么。我可以将Redux操作包含在承诺中吗?我是否误用了Thunk?或者我应该完全尝试不同的模式吗?

1 个答案:

答案 0 :(得分:6)

  

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

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

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

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

至于你的具体问题,

  

我发现当发送其中一个过滤方法时,在调用filterItems()时,商店(状态#2)尚未更新。

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

但是,在任何情况下,filterItems()都不适合某个操作,我建议您按照我上面的说法来研究mapStateToProps()中的过滤。