reactjs - 我应该如何按照单一责任模式处理组件状态
问题描述
我是 ReactJs 的新手,并试图遵循最佳实践。根据我的研究,我遇到了几篇相互矛盾的文章,讨论了应该如何实现。
状态是否应该依赖于从父组件传递下来的属性?在下面的比较中,它们都遵循 SRP,但不确定哪个是最好的。希望得到您的建议,谢谢!
1. -- React.js 中组件状态的最佳实践
首先,可能也是最重要的一点,组件的状态不应依赖于传入的 props。(请参阅下面的示例,了解我们不应该做什么)
class UserWidget extends React.Component {
// ...
// BAD: set this.state.fullName with values received through props
constructor (props) {
this.state = {
fullName: `${props.firstName} ${props.lastName}`
};
}
// ...
}
2. --一个可靠的 React 组件的 7 个架构属性
让我们重构一个职责:渲染表单字段并附加事件处理程序。它应该不知道如何直接使用存储......组件从一个道具initialValue接收存储的输入值,并使用道具函数saveValue(newValue)保存输入值。这些 props 由 withPersistence() HOC 使用 props 代理技术提供。
class PersistentForm extends Component {
constructor(props) {
super(props);
this.state = { inputValue: props.initialValue };
}
// ...
}
3. -- 在我的情况下,我有类似以下的内容(想知道这是否是一个可接受的实现?) - 状态应该在 Tasks 中处理,还是在位于 TasksWithData 和 Tasks 之间的另一个 TasksWithPersistence 类型的组件中处理?
export default function TasksWithData(TasksComponent) {
return class withData extends React.Component {
render() {
const tasks = TaskAPI.getTasks();
return (
<TasksComponent
tasks={tasks}
{...this.props}
/>
)
}
}
}
export default class Tasks extends React.Component {
state = {
tasks: [],
addItemInput: null
};
// ...
componentDidMount() {
this.updateComponentState({tasks: this.props.tasks});
}
componentDidUpdate() {
this.prepUIForNextAddition();
}
// ...
}
解决方案
示例 1 和示例 2 之间存在巨大差异。
在示例 #1 中,以这种方式从这些道具设置状态是不好的原因是,如果道具更改,小部件将不会更新。最佳实践与否,在任何框架中都是错误和糟糕的。在那种特殊情况下,即使使用状态也没有任何意义。仅道具就足够了。
在示例 #2 中,prop 仅用于为 state 赋予初始值(prop 甚至被命名为initialValue
),这意味着对 state 的进一步更改将由组件控制,而不管 prop 更改如何。将 props 用于初始状态并不会违反单一职责原则,尤其是当它明确用于该目的时。
我真的不认为这两个例子是矛盾的,因为它们完全不同。此外,单一职责原则中没有规定您不能从道具设置状态,您只需要注意您正在执行的上下文。
推荐阅读
- sql - 我的 SQL 代码没有提取 MS Access 中的数据
- javascript - 用户位置不返回任何值
- java - 为什么在静态初始化程序中使用并行流会导致不稳定的死锁
- java - Java 龟博士项目——我似乎无法调试我的错误
- php - laravel save() 方法会抛出异常吗?
- c++ - CMake包含系统和项目头文件之间的路径冲突
- timestamp - 似乎无法将时间戳转换为正确的日期时间
- mysql - 检查日期列是否在某个时期,这取决于另一个日期列
- javascript - 旧文件从 jQuery 文件上传控件中删除
- python-2.7 - 来自客户端-服务器(udp)连接python 2.7的数据包嗅探器(仅限)