setState没有正确更新状态 [英] setState is not updating state properly
问题描述
抱歉,我真的很想念React中子组件的 props
中传输州
。
Sorry, I really miss something with the transmission of state
within props
of sub components in React.
我已经实现了一个包含3个组件的待办事项列表版本。
I have implemented a version of a todo list with 3 components.
有一个表单
组件和 ListTodo
组件。状态仅存储在 App
组件中。
There is a Form
component and a ListTodo
component. The state is stored only in the App
component.
import React, {Component} from 'react';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
tasks: ["un truc", "autre truc"]
};
this.addTask = this.addTask.bind(this);
}
addTask(task) {
this.setState({
tasks: this.state.tasks.push(task)
})
}
render() {
return (
<div className="App">
<Form onTaskAdded={ this.addTask }></Form>
<ListTodo tasks={ this.state.tasks }></ListTodo>
</div>
);
}
}
class Form extends Component {
constructor(props) {
super(props);
this.state = {
task: ""
}
this.handleChange = this.handleChange.bind(this);
this.addTask = this.addTask.bind(this);
}
handleChange(event) {
this.setState({
task: event.target.value
});
}
addTask(event) {
this.props.onTaskAdded(this.state.task);
event.preventDefault();
}
render() {
return (
<form onSubmit={ this.addTask }>
<input placeholder="À faire" onChange={ this.handleChange }></input>
<input type="submit"></input>
</form>
)
}
}
class ListTodo extends Component {
render() {
const tasks = this.props.tasks.map((t, i) => (
<li key={i}>{t}</li>
))
return (
<ul>{tasks}</ul>
)
}
}
export default App;
显示效果良好,所以 ListTodo
实现看到道具任务
。但是在提交表单后,我在 ListTodo.render
上收到错误:
The display is good at start so the ListTodo
achieves to see the prop tasks
. But after a form submission, I get an error on ListTodo.render
:
TypeError:this.props.tasks.map不是函数
TypeError: this.props.tasks.map is not a function
当我在console.log中时,这个。 props.tasks
,我没有得到我的数组但是数组的长度。
When I console.log the this.props.tasks
, I don't get my array but the length of the array.
你知道为什么吗?
编辑:
感谢您的回答,你说得对。我错过了Array.push的行为。
Edit : Thanks for answers guys, you're right. I missed the behavior of Array.push.
但是React似乎仍然很奇怪。如果我让错误的代码
this.setState({
tasks:this.state.tasks.push(task)
})
But React seems still odd. If I let the mistaken code
this.setState({
tasks: this.state.tasks.push(task)
})
然后一个 console.log(JSON.stringify(this.state))
显示:
{tasks:[un truc,autre truc,aze]}
。
非常令人不安,无法信任console.log ...
Very disturbing to not be able to trust a console.log...
推荐答案
根据 MDN DOC :
push()方法将一个或多个元素添加到数组的末尾并且
返回数组的新长度。
Array.push 永远不会返回结果数组,它会返回数字,所以在添加第一个任务后, this.state.tasks
变成一个数字,当你试图在数字上运行地图时它会抛出错误。
Array.push never returns the result array, it returns the number, so after adding the first task, this.state.tasks
becomes a number, and it is throwing the error when you trying to run map on number.
你在这里犯了错误:
addTask(task) {
this.setState({
tasks: this.state.tasks.push(task)
})
}
这样写:
addTask(task) {
this.setState( prevState => ({
tasks: [...prevState.tasks, task]
}))
}
这里的另一个重要的事情是,新状态将取决于之前的状态值,所以不要在setState内使用 this.state
,使用更新程序功能。
Another import thing here is, the new state will be depend on the previous state value, so instead of using this.state
inside setState, use updater function.
关于编辑部分的说明:
两个重要的事情是发生在那里:
Two important things are happening there:
1 - setState是异步的,因此在setState之后我们可以期待更新的状态值。
1- setState is async so just after setState we can expect the updated state value.
检查此项以获取有关 setState的异步行为 。
Check this for more details about async behaviour of setState.
2 - Array.push始终改变原始状态通过将项目推入该数组,所以你通过 this.state.tasks.push()
直接改变状态值。
2- Array.push always mutate the original array by pushing the item into that, so you are directly mutating the state value by this.state.tasks.push()
.
检查 DOC ,了解有关setState的更多详细信息。
Check the DOC for more details about setState.
检查 传播运营商(...)的Spread_operatorrel =nofollow noreferrer> MDN Doc 。
Check the MDN Doc for spread operator (...)
.
检查此代码段:
let a = [1,2,3,4];
let b = a.push(5); //it will be a number
console.log('a = ', a);
console.log('b = ', b);
这篇关于setState没有正确更新状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!