reactjs - 如何过滤 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;
}
注意两个减速器如何观察相同的动作并对其采取行动(显示加载动画)。现在,如果这些减速器相关的屏幕/组件都在内存中,这START_FETCH
将导致它们都显示加载动画,甚至可能重叠(因为它是全局的)。按屏幕/组件过滤操作是一个好的解决方案吗?
像这样:
function reducerComponentA(state, action) {
if (action.currentScreen === 'ScreenA') {
switch (action.type) {
...
}
}
return state;
}
这在 React Native 上似乎是一个更大的问题,因为如果您使用的是 Navigator,则有可能同时加载多个屏幕。
解决方案
您可以将减速器“安装”到状态的不同部分。为此,您可以添加path
到操作中,并在减速器中更新相应的状态切片。
它可以类似于:
function reducer(state, action) {
if (action.type === '...') {
return _.set(_.deepClone(state), `${action.path}.isLoading`, false)
} else return state;
}
换句话说,action 决定了 state reducer 的哪一部分将被操作。
请注意,上面的示例效率极低,仅用于演示目的。与其克隆状态,不如使用一些不变性助手:kolodny/immutability-helper、mweststrate/immer等。
UPD
想象一下,你有一个输入状态的 action 和 reducer:
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'))
答案开头的代码是后者的通用版本。
推荐阅读
- php - Laravel 从 URL 获取未命名的“GET”参数 id
- javascript - 如何将按钮和输入元素添加到下拉列表中
- javascript - 怎样才能让用户做一次QUIZZ?
- android - 使用毕加索将base64字符串加载到imageview中
- ruby - 如何使用.include?捕获导致相同操作的多个选项
- php - 如何对“私有”构造函数进行例外处理?
- java - 如何在 Java 8 的范围内生成具有指定大小的随机整数的列表?
- c# - Unity3D 引擎类中不应该出现一致的“CS0201”错误
- regex - 如何计算最后出现在单元格中的Google表格单元格中特定字符的出现次数作为标准?
- java - 不兼容的类型。必需:T,找到 T。为什么?