如何过滤Redux操作?

时间:2018-05-23 21:13:27

标签: reactjs react-native redux react-redux

是否可以向动作添加更多信息,以便特定于组件的减速器(以及sagas /您正在使用的任何副作用)可以过滤它们?

示例:

function reducerComponentA(state, action) {
  switch (action.type) {
    case START_FETCH:
      return {
        ...state,
        isLoading: true,
      };
      break;

    case START_FETCH_SUCCESS:
      return {
        ...state,
        isLoading: false,
      };
      break;
  }

  return state;
}

function reducerComponentB(state, action) {
  switch (action.type) {
    case START_FETCH:
      return {
        ...state,
        isLoading: true,
      };
      break;

    case START_FETCH_SUCCESS:
      return {
        ...state,
        isLoading: false,
      };
      break;
  }

  return state;
}

注意两个reducers如何观察相同的动作并对它们进行操作(显示加载动画)。现在,如果这些缩减器所关联的屏幕/组件都在内存中,START_FETCH将导致它们都显示加载动画,甚至可能重叠(因为它是全局的)。屏幕/组件的过滤操作是一个很好的解决方案吗?

像这样:

function reducerComponentA(state, action) {
  if (action.currentScreen === 'ScreenA') {
    switch (action.type) {
      ...
    }
  }

  return state;
} 

这似乎是React Native的一个问题,因为如果您使用导航器,则有可能同时加载多个屏幕。

1 个答案:

答案 0 :(得分:0)

你可以安装'减速机到不同的切片状态。要实现此目的,您可以将path添加到操作中,并在reducer中更新相应的状态切片。

它可以类似于:

function reducer(state, action) {
  if (action.type === '...') {
    return _.set(_.deepClone(state), `${action.path}.isLoading`, false)
  } else return state;
}

换句话说,动作决定状态减速器的哪个部分将用于操作。

请注意,上面的示例效率极低,仅用于演示目的。应该使用一些不变性助手而不是克隆状态:kolodny/immutability-helpermweststrate/immer,其他。

UPD

想象一下,你有一个输入状态的动作和减速器:

const UPDATE_VALUE = 'UPDATE_VALUE';
const updateValue = (value) => ({ type: UPDATE_VALUE, value })

function reducer(state, action) {
  if (action.type === UPDATE_VALUE) {
    return { ...state, input: action.value }
  } else return state;
}

并且您希望将此动作/减速器用于许多不同的输入。可以提供动作 一个属性路径,指示应更新哪个部分或状态,以及最终输入哪个 将收到新的道具:

const UPDATE_VALUE = 'UPDATE_VALUE';
const updateValue = (value, path) => ({ type: UPDATE_VALUE, value, path })

function reducer(state, action) {
  if (action.type === UPDATE_VALUE) {
    return { ...state, [action.path]: action.value }
  } else return state;
}

然后可以使用:

dispatch(updateValue(event.target.value, 'firstNameInput'))
dispatch(updateValue('Doe', 'lastNameInput'))

答案开头的代码是后者的通用版本。