Я учусь реагировать, что лучше всего подходит для следующего сценария? (Обратите внимание, только что напечатал это - не идеально, просто для иллюстрации того, что я пытаюсь сделать). Учитывая эти данные -
const person = {
name: "",
tasks: [
{name: "", done: false }
]
}
Я хочу, чтобы форма редактировала и название, и задачи одновременно - добавляла, удаляла и редактировала поля задач.
О чем я думал:
<PersonForm>
<PersonName />
<TaskList />
</PersonForm>
Имя можно легко отредактировать на примере, приведенном в документации по реакции:
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 = ???...
. . .
Но,
Мне кажется, что лучший способ инкапсулировать функциональность - это добавить функциональность addTask, deleteTask, updateTask в компоненте TaskList. Я ошибся?
Кажется, что в противном случае PersonForm стал бы огромным (в реальном примере). Означает ли это, что TaskList потребуется состояние?
В основном,





Вынос некоторой логики за пределы компонента, когда он становится огромным, имеет смысл, но в то же время удобно хранить все состояния формы в одном месте. Вы можете использовать ref для дочернего компонента, чтобы получить его состояние, но это уродливое решение и считается плохой практикой. Я считаю, что по своему опыту я не сталкивался с очень огромными формами, поэтому, даже если они были большими компонентами, было довольно хорошо читать/управлять всем состоянием там. Но если вы действительно хотите убрать из него какую-то логику, я думаю, вы могли бы, например, использовать новый контекстный API для хранения состояния формы (или просто состояния списка задач) и подписаться на него в компоненте PersonForm (для чтения) и в TaskList (читать и изменять).