[英]React parent component reseting child components state when parent state updates
我有一个名为ToDoLists
的父组件,它包含一个输入并允许您输入一个新的待办事项列表名称。 此组件映射组件状态中的列表数组以创建不同的List
组件。
List
组件允许您添加待办事项。 例如:早上例行清单,包括早餐、淋浴、刮胡子等待办事项。
我可以使用ToDoLists
组件来创建新的List
组件。 但是,当我在List
组件中添加 todo 项时,在父组件的输入中重新输入状态似乎会擦除子组件的状态。
我不确定这是否是尝试这样做的正确方法。 这是因为我在添加新列表时需要传递prevState
吗?
待办事项列表组件
import React, { Component } from 'react';
import '../App.css';
import List from './list.js';
class ToDoLists extends Component {
constructor(props){
super(props)
this.state = {
term: '',
list: []
};
}
onChange = (event) => {
this.setState({term: event.target.value});
}
onSubmit = (event) => {
event.preventDefault()
this.setState({
term: '',
list: [...this.state.items, this.state.term]
})
}
render() {
const generateKey = (x) => {
return `${x}_${new Date().getTime()}`
};
return(
<div>
<h3>ToDo Lists Component</h3>
<form onSubmit={this.onSubmit}>
<input placeholder='Add A New List' value={this.state.term} onChange={this.onChange}/>
<button className='btn btn-sm btn-dark'>Submit</button>
</form>
<br/><br/>
{
this.state.list.map((data) => {return(<List title={data} key={generateKey(data)}/>)})
}
</div>
)
}
}
export default ToDoLists
列表组件
import React, { Component } from 'react';
import '../App.css';
class List extends Component {
constructor(props){
super(props)
this.state = {
term: '',
items: []
};
this.onChange = this.onChange.bind(this);
}
onChange = (event) => {
this.setState({term: event.target.value});
}
onSubmit = (event) => {
event.preventDefault()
this.setState({
term: '',
items: [...this.state.items, this.state.term]
})
}
render() {
const generateKey = (x) => {
return `${x}_${new Date().getTime()}`
}
return(
<div>
<h3>{this.props.title}</h3>
<form onSubmit={this.onSubmit}>
<input placeholder='Add New Todo Item' value={this.state.term} onChange={this.onChange}/>
<button className='btn btn-sm btn-dark'>Submit</button>
</form>
<ul>
{
this.state.items.map((item) => {return(<li key={generateKey(item)}>{item}</li>)})
}
</ul>
</div>
)
}
}
export default List
重置是由这个小部分引起的:
key={generateKey(data)}
每当您重新渲染父项时,子项都会获得新密钥,因为generateKey
返回一个几乎随机的密钥。 当差异化时,React 会尝试找出哪些组件被移除,哪些组件被添加,并使用key
prop 来简化这一点。 如果一个键是前一个子元素和当前子元素的一部分,则元素保持原样,如果键消失,组件将被销毁,如果键是新的,它将创建一个新组件。 因此,在您的情况下,每当ToDoLists.render()
运行时,所有List
都将被销毁并创建新的。 要改变它,只需使key
持久化:
const generateKey = (x) => {
return "" + x;
}
(如果两个列表可能具有相同的名称,最好将 Lists 索引作为键。)
虽然这样做有效,但现在实际上很难存储状态,因为它被分成多个组件。 因此,您可能想要“提升状态”,以便在父级中管理所有列表,并且每个更改都会传播到该父级:
class ToDoLists extends React.Component {
constructor(props) {
super(props);
this.state = { lists: [] };
}
updateList(old, updated) {
this.setState(({ lists }) => ({ lists: lists.map(l => l === old ? updated : l) }));
}
render() { return this.state.lists.map(list => <List list={list} onChange={updated => this.updateList(list, updated)} />); }
}
class List extends React.Component {
onSubmit() {
const { onChange, list } = this.props;
this.setState({ term: "" });
onChange([...list, this.state.term]);
}
//...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.