我正在学习做出反应,以下情况的最佳实践是什么? (请注意,只是键入了这一点-并不完美,只是为了说明我正在尝试做的事情)。给定此数据-
const person = {
name: "",
tasks: [
{name: "", done: false }
]
}
我希望表单同时编辑名称和任务-添加,删除和编辑任务字段。
我在想什么:
<PersonForm>
<PersonName />
<TaskList />
</PersonForm>
可以通过react文档给出的示例轻松地编辑名称:
class PersonForm extends React.Component {
constructor(props) {
this.state = {
name: "",
tasks: [
{name: "", done: false }
]
};
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({ [name]: value });
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<PersonName name={this.state.name} onChange={this.handleInputChange} />
<TaskList tasks={this.state.tasks}
deleteTask={this.deleteTask}
addTask={this.addTask}
updateTask={this.updateTask}/>
<input type="submit" value="Submit" />
</form>
);
}
}
class PersonName extends
render() {
return (
<label>
Name:
<input type="text" name="name" value={this.props.value} onChange={this.props.onChange} />
</label>
)
}
}
我知道建议是提升状态。因此,我可以将addTask,removeTask和updateTask回调方法放在PersonForm中。
class PersonForm extends React.Component {
. . .
addTask = event => {
this.setState(prev => ({ tasks: [...prev, {name: "", done: false}]}));
}
removeTask = key => {
this.setState(prev => ({ tasks: prev.filter(t => t.key !== key) });
}
updateTask = ???...
. . .
但是
在我看来,最好的封装功能的方法是在TaskList组件中使用addTask,deleteTask和updateTask功能。我错了吗?
看来,否则PersonForm会变得很大(在现实世界的示例中)。这是否意味着TaskList需要状态?
基本上,
答案 0 :(得分:1)
在组件开始变得庞大时将一些逻辑移出组件是有意义的,但同时将所有表单状态保持在一个位置也很方便。您可以在子组件上使用ref
来检索其状态,但这是一个丑陋的解决方案,被认为是一种不好的做法。我相信,根据我的经验,我并没有遇到过非常庞大的表格,因此即使它们是很大的组成部分,也可以很好地读取/管理那里的所有状态。但是,如果您真的想从中删除一些逻辑,例如,可以使用新的上下文API存储表单的状态(或仅任务列表的状态)并在PersonForm
组件中进行订阅(以阅读)和TaskList
中(以阅读和更改)。