this is app.js
class App extends Component {
constructor() {
super();
this.state = {
todo_lists: [
{ id: 1, name: "Hoc React" },
{ id: 2, name: "Hoc HTML" },
{ id: 3, name: "Hoc Jquery" },
{ id: 4, name: "Hoc CSS" }
],
showList : []
};
}
componentDidMount(){
let {showList, todo_lists} = this.state
this.setState({
showList : [...todo_lists]
})
console.log(showList)
}
}
when console.log(showList) on browser it return empty array like this [], clearly I assigned showList: [...todo_lists] in setState. help me
Issue:
// this.setState is async method
this.setState({
showList : [...todo_lists]
});
console.log(showList) // <--- this will not give you updated value right after
you can use this.setState
callback
method for that, it is being called right after the state is set
this.setState({
// showList : [...todo_lists]
showList : this.state.todo_lists.map(todo => ({ ...todo}))
},() => {
console.log(this.state.showList) //<------ Check here
})
Suggestion:
constructor() {
super();
this.todos = [
{ id: 1, name: "Hoc React" },
{ id: 2, name: "Hoc HTML" },
{ id: 3, name: "Hoc Jquery" },
{ id: 4, name: "Hoc CSS" }
]
this.state = {
todo_lists: this.todos.map(todo => ({ ...todo})),
showList : this.todos.map(todo => ({...todo}))
};
}
From Reactjs.org
Think of setState() as a request rather than an immediate command to update the component. For better perceived performance, React may delay it, and then update several components in a single pass. React does not guarantee that the state changes are applied immediately.
https://reactjs.org/docs/react-component.html#setstate
So what you wrote will NOT happen immediately, and your console.log will NOT get the right values immediately afterwards.
The problem here is that React's setState is an async method, so it may delay the update in favor of perceived improvement in performance.
What you could do, is something like this (if you don't want to use the callback provided by the setState) :
componentDidMount() {
const {showList, todo_lists} = this.state,
nextShowList = [...todo_lists];
this.setState({
showList: nextShowList
});
console.log(nextShowList); // executes immediatelly
}
If you want to use the callback provided by the setState method, simply use it like this:
componentDidMount() {
const {showList, todo_lists} = this.state;
this.setState({
showList: [...todo_lists]
}, () => console.log(this.state.showList)); // MAY NOT execute immediately
}
Also, as an additional tip (if I may), use the first argument as a function, or you may have problems setting your todo_list!
componentDidMount() {
this.setState(prevState => {
return {
showList: [...prevState.todo_lists]
};
}, () => console.log(this.state.showList));
}
Again, for the same reason: Since setState is async, you can't guarantee that the this.state outside of the setState is up-to-date!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.