【问题标题】:React Redux dispatch 2 actions based on conditionReact Redux 根据条件调度 2 个动作
【发布时间】:2017-10-18 12:46:08
【问题描述】:

我正在尝试更改 (addList) 事件上的存储,并检查这是否是第一个要触发 (selectList) 事件的列表数组并将其添加到 (state.selectedList.list)。现在,只要 onClick 事件在列表数组上工作,就会使用 (selectList)。 问题是我应该何时以及如何处理添加第一个列表到 selectedList 的事件,而不是像我之前使用的那样仅使用 (selectList) onClick 事件。

export default connect(
      state => ({
        lists: getEntities('lists')(state),
        selectedList: state.selectedList.list
      }),
      dispatch => ({
        addList: (name) => dispatch({type: 'ADD_LIST', payload: name}),
        selectList: (listId) => dispatch({type: 'CHANGE_SELECTED_LIST', payload: listId})
      })
    )(Lists)

【问题讨论】:

    标签: javascript reactjs react-redux redux-saga


    【解决方案1】:

    如果您同时拥有nameid 通过单击添加的列表,则可以直接在 addList 处理程序中完成:

    addList(name, id) { // bound with click
      const size = this.props.lists.length
      this.props.addList(name)
      if(!size) {
        this.props.selectList(id)
      }
    }
    

    否则,您需要等待列表创建(以获取id)然后调度 selectList 操作。最肮脏的解决方案可能只是:

    addList(name) { // bound with click
      const size = this.props.lists.length
      this.props.addList(name)
      if(!size) {
        // don't do that! it's just for proof of concept
        setTimeout(() => this.props.selectList(this.props.lists[size].id))
      }
    }
    

    更进一步,你可以使用componentWillReceiveProps钩子捕捉lists.length变成1,然后正常触发selectList

    componentWillReceiveProps(nextProps) {
      const previousSize = this.props.lists.length
      const size = nextProps.lists.length
      if(previousSize === 0 && size === 1) {
        this.props.selectList(nextProps.lists[size].id))
      }
    }
    

    另一个选项是 reducer,我们不处理新列表 id,而只处理以前的列表大小(并且不需要额外的操作触发器):

    case ADD_LIST:
      return {...state,
        lists: [...state.lists,
          action.newList
        ],
        selectList: {...state.selectList,
          list: !state.lists.length ? action.newList : state.selectList.list
        }
      }  
    

    最后,动作创建者(我最喜欢的)代替了以上所有内容:

    export function addList(name) {
      return (dispatch, getState) => {
        const size = getState().lists.length
        const newList = generateNewListByName(name)
        dispatch({
          type: ADD_LIST,
          newList
        })
        if(size === 0)
          dispatch({
            type: CHANGE_SELECTED_LIST,
            selectedListId: newList.id
          })
        }
      }
    }
    

    最后一点需要适应您的基础架构,但主要思想保持不变:根据之前的状态条件 (size === 0) 执行一些逻辑。

    【讨论】:

    • 但是如果我没有使用类组件并且无权访问componentWillReceiveProps,而是功能组件?
    • @serj 我在aswer中添加了一些想法,它们可以应用于功能组件的情况。
    猜你喜欢
    • 2021-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-03
    • 1970-01-01
    • 2021-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多