我目前正在使用 React Native 开发一个应用程序。应用程序的状态非常复杂,但由于 Redux 和 Normalizr 是可以管理的。我现在必须为用户实现过滤项目的功能。
为了让用户过滤项目,我在 Normalizr 模式中丰富了服务器响应:
export const subCategorySchema = new schema.Entity(
"subCategories",
{},
{
idAttribute: "uuid",
processStrategy: entity => {
const newEntity = Object.assign({}, { name: entity.name, uuid: entity.uuid, chosen: false });
return newEntity;
}
}
);
对应的 reducer 现在看起来像这样:
const initialState = {};
const subCategoriesReducer = (state = initialState, action) => {
if (action.payload && action.payload.entities) {
return {
...state,
...action.payload.entities.subCategories
};
} else {
return state;
}
};
这些子类别现在使用此 SwitchListItem 组件显示在 UI 中,该组件通过选择器获取其项目:
import React, { Component } from "react";
import { Switch, Text, View } from "react-native";
import PropTypes from "prop-types";
import styles, { onColor } from "./styles";
export default class SwitchListItem extends Component {
static propTypes = {
item: PropTypes.object
};
render() {
const { name, chosen } = this.props.item;
return (
<View style={styles.container}>
<Text style={styles.switchListText}>{name}</Text>
<Switch style={styles.switch} value={chosen} onTintColor={onColor} />
</View>
);
}
}
我现在要实现<Switch />
组件的onValueChange()
功能,这就是我的问题所在:
在标准化状态树中切换布尔值的最佳方法是什么?
我想出了两个解决方案,我将在下面描述。如果您认为其中任何一个是好的,请告诉我。如果不是,我很想得到关于我可以做得更好的建议:)
解决方案1:扩展reducer:
我对这个问题的第一个解决方案是扩展 reducer 来监听TOGGLE_ITEM
动作。这看起来像这样:
const subCategoriesReducer = (state = initialState, action) => {
switch (action.type) {
case TOGGLE_ITEM:
if (action.payload.item.uuid in state) return { ...state, ...action.payload.item };
}
if (action.payload && action.payload.entities) {
return {
...state,
...action.payload.entities.subCategories
};
} else {
return state;
}
};
这是我的首选解决方案,因为它不需要大量代码。
解决方案 2:丰富将项目传递给的选择器SwitchList
:
另一种解决方案是丰富对象,同时使用具有状态键的选择器将其传递到列表。然后我可以创建一个使用此键更新状态的操作,如下所示:
const toggleItem = (item, stateKey) => ({
type: TOGGLE_ITEM,
payload: {entities: { [stateKey]: item } }
})
如果您对 Redux 有丰富的经验,我很想阅读一个答案,最好是固执己见。另外,如果您认为我在 normalizr 中丰富数据的方法不好,您可以提出更好的方法,请告诉我!非常感谢您的任何建议!