为React可重用组件设计Redux动作和reducer
Design Redux actions and reducers for a React reusable component
我正在用Redux和React开发一个大型应用程序,我决定制作一些可重用的组件,如自定义复选框和单选按钮。
由于我想将这些信息存储到Redux存储中,以便能够轻松地调试应用程序的状态,并且相同的组件在任何地方都具有相同的功能,因此为每个组件创建reducer和action似乎是一个好主意。
然而,Redux的reducer返回一个新的状态,并将其保存在存储中,并以reducer的名称作为键,这禁止在同一页面中使用相同的操作和reducer的多个相同类型的组件,但保持不同的状态。
我认为有两种方法可以解决这个问题:
-
为我使用的每个组件创建不同的动作和减速器,即使组件及其功能是相同的。这个解决方案似乎不是一个好的解决方案,因为会有很多冗余的代码。
-
创建具有足够参数的动作,以便能够区分减速机中的每个动作,并且这样只改变指定的部分状态。
我选择了第二个选项。
CheckBox组件的动作文件:
import {createAction} from 'redux-actions';
/****** Actions ******/
export const CHANGE_CHECKBOX_STATE = "CHANGE_CHECKBOX_STATE";
/****** Action creators ******/
export const changeCheckboxState = createAction(CHANGE_CHECKBOX_STATE, (block, name, state) => {
return {
block,
name,
state: {
checked: state,
}
};
});
CheckBox组件的reducer文件
import {handleActions} from 'redux-actions';
import {CHANGE_CHECKBOX_STATE} from './CheckBox.actions';
export const checkBoxComponent = handleActions({
CHANGE_CHECKBOX_STATE: (state, action) => ({
[action.payload.block]: {
[action.payload.name]: action.payload.state
}
})
}, {});
我使用block
来指定页面,name
来指定特定组件的名称(例如性别),并使用状态作为具有新状态的对象。
但是这个解决方案也有一些问题:
- 不能指定每个组件的初始状态,因为状态键是动态的。
- 使存储结构变得非常复杂,有很多嵌套状态。
- 按组件而不是按形式聚合数据,这会使调试复杂化,并且在逻辑上是不正确的。
我没有足够的Redux和React经验来思考这个问题的更好解决方案。但在我看来,我似乎错过了一些重要的关于React-Redux关系,这提出了一些问题:
将这个可重用组件的状态存储到Redux存储中是一个好主意吗?
我在将React组件与Redux动作和reducer绑定在一起是错误的吗?
不要根据使用该状态的组件来描述您的Redux reducer(您的整个应用程序状态)。以另一种方式跟踪它,以描述性的方式描述应用程序状态,然后让"哑"组件使用该描述性状态。
与其跟踪"与foo相关的表单的这个复选框的状态",不如跟踪"foo的这个布尔值",然后让复选框消耗那个状态。
复选框的存储示例:
const initialState = {
someFooItem: { isCertainType: false }
};
export function foos(state = initialState, action) {
switch(action.type){
case(UPDATE_FOO_VALUE):
return {
...state,
[action.payload.id]: {
isCertainType: action.payload.isCertainType
}
}
}
}
使用存储
的示例复选框class CheckBox extends React.Component {
render() {
return <input type="checkbox" checked={this.props.checked} />
}
}
父组件
class ParentComponent extends React.Component {
render() {
return <CheckBox checked={this.foo.isCertainType} />
}
}
这里最根本的错误是没有哑组件。像复选框这样的基本控件应该是只使用props的哑组件,它们的父控件负责为特定的复选框选择和更新适当的状态。
- 在达到状态之前在Redux Reducer中设置日期格式
- Redux:为什么不把操作和reducer放在同一个文件中呢
- React+Redux-期望reducer是一个函数
- 为什么这个reducer不使用redux触发视图更改
- Redux请参阅Reducer中的其他状态
- React+Redux router=未捕获错误:要求reducer是一个函数
- Redux:在reducer中过滤数据数组的正确方法是什么
- Redux: reducer的全局配置
- React Redux Reducer: 'this.props.tasks.Map不是函数'错误
- 用React和redux从不同的reducer调用一个动作
- Redux reducer删除数组元素失败
- 如何在redux框架中使用Action和Reducer记录响应时间
- 如何处理Redux reducer中的树形实体
- Redux reducer初始化相同的状态键
- 为React可重用组件设计Redux动作和reducer
- 在redux reducer中调用一个操作
- 如何访问Redux reducer内部的状态
- 在react redux reducer中替换new state而不创建副本
- 我应该基于调用来组织我的react redux reducer组合还是基于一个reducer管理的状态
- Redux:在reducer函数中调用store.getState()是一种反模式