javascript - setState is not updating state properly -
sorry, miss transmission of state within props of sub components in react.
i have implemented version of todo list 3 components.
there form component , listtodo component. state stored in app component.
import react, {component} '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; the display @ start listtodo achieves see prop tasks. after form submission, error on listtodo.render :
typeerror: this.props.tasks.map not function
when console.log this.props.tasks, don't array length of array.
do know why?
edit : answers guys, you're right. missed behavior of array.push.
but react seems still odd. if let mistaken code this.setstate({ tasks: this.state.tasks.push(task) })
then console.log(json.stringify(this.state)) displays :
{"tasks":["un truc","autre truc","aze"]}.
very disturbing not able trust console.log...
as per mdn doc:
the push() method adds 1 or more elements end of array , returns new length of array.
array.push never returns result array, returns number, after adding first task, this.state.tasks becomes number, , throwing error when trying run map on number.
you did mistake here:
addtask(task) { this.setstate({ tasks: this.state.tasks.push(task) }) } write this:
addtask(task) { this.setstate( prevstate => ({ tasks: [...prevstate.tasks, task] })) } another import thing here is, new state depend on previous state value, instead of using this.state inside setstate, use updater function.
explanation edit part:
two important things happening there:
1- setstate async after setstate can expect updated state value.
check more details async behaviour of setstate.
2- array.push mutate original array pushing item that, directly mutating state value this.state.tasks.push().
check doc more details setstate.
check mdn doc spread operator (...).
check snippet:
let = [1,2,3,4]; let b = a.push(5); //it number console.log('a = ', a); console.log('b = ', b);
Comments
Post a Comment