我在redux中对全局状态和可重用组件的概念进行了一些努力。
我们说我有一个组件,它是一个文件选择器,我想在我的应用程序状态中的多个位置使用。创建动作/减速器会导致很多臃肿,因为我必须处理具有动态后缀和其他奇怪事物的状态,这些事情并不会让我成为一种聪明的事情。
对这些事情的普遍共识是什么?我只能看到两个解决方案:
使文件选择器组件具有本地状态(this.setState/this.getState
)
让文件选择器成为全局状态的一部分,但是在它完成组件的操作后,我可以读取它自己的唯一缩减器吗?
任何想法/最佳做法?感谢。
更新:澄清我所描述的文件选择器不是一个纯粹在客户端工作的简单组件,但必须从服务器获取数据,提供分页以及过滤等。这就是为什么我也想重用大多数客户端/服务器交互的原因。显示此组件的视图当然是愚蠢的,只显示来自状态的值 - 但是如何在应用程序周围的多个位置重用操作/缩减器?
答案 0 :(得分:3)
让您的reducer处理组件状态的多个实例。只需定义一些" unique" FileBrowser组件的每个实例在应用程序中出现时的ID,并将当前状态包装为具有此唯一ID作为键的对象,并将旧复杂状态作为值包装。
这是我多次使用的技术。如果在编译时知道所有FileBrowser,您甚至可以在运行应用程序之前设置初始状态。如果你需要支持"动态"实例,只需创建一个初始化给定id的状态的Action。
您没有提供任何代码,但这是一个可重复使用的Todo减速器的人为例子:
function todos(state={}, action){
switch(action.type){
case 'ADD_TODO':
const id = action.todoListId
return {
...state,
[id]: {
...state[id],
todos: [ ...state[id].todos, action.payload ]
}
}
// ...
}
}
答案 1 :(得分:1)
通常,经验法则是您使用redux store
管理应用程序中的数据,即存储从服务器获取的项目和本地react state
的ui行为,例如文件上传。我制作了一个纯粹的反应组件来管理文件上传,然后使用redux-form来管理特定的表单。
以下是我在项目中使用的组件的示例
import React, {Component, PropTypes} from 'react';
import Button from 'components/Button';
class FileButton extends Component {
static propTypes = {
accept: PropTypes.string,
children: PropTypes.any,
onChange: PropTypes.func.isRequired
};
render() {
const {accept, children, onChange} = this.props;
return <Button {...this.props} onClick={() => this.file.click()}>
<input
ref={el => this.file = $(el)}
type="file"
accept={accept}
style={{display: 'none'}}
onChange={onChange}
/>
{children}
</Button>;
}
}
export default FileButton;
答案 2 :(得分:1)
我们得出结论,可重用组件必须有两种:
哑组件,即仅接收道具并触发&#34;动作&#34;仅通过道具回调。这些组件具有最小的内部状态或根本没有。这些是最常见的可重用组件,在这种情况下,您的文件选择器可能会出现问题。样式化的文本输入或自定义列表也是很好的例子。
连接的组件,提供自己的操作和reducer。这些组件在应用程序中有自己的生命,并且与其他组件相互独立。一个典型的例子是&#34;顶部错误消息框&#34;当应用程序严重失败时,它会显示在其他所有内容之上。在这种情况下,应用程序会触发&#34;错误操作&#34;将相应的消息作为有效负载,并在以下重新呈现时,消息框显示在其余部分之上。