How to Set State with arguments passed to a function in React
The issue might be that you are expecting this.setState
to be synchronous. See the documentation here.
Take a look at this CodeSandbox demo. this.setState
accepts a callback as the second argument. This callback is invoked after this.setState
has completed.
Notice how in the console.log
output, we can see the old
and new
state values.
georgeperry
Trying to make it in the big bad world of software development! Team JS
Updated on June 05, 2022Comments
-
georgeperry almost 2 years
I'm trying to pass an array (titles) from a child component to the parent, then set the state of the parent with the array. However, when handling the change in the increaseReads() method, I cannot change the articlesRead state
You will see two console.log() statements; the first one is successfully logging the titles but the second is logging an empty array - the previous state
The Child:
export class Publication extends React.Component { constructor() { super(); this.state = { items: [] }; } componentDidMount() { fetch(this.props.url) .then(response => { return response.json(); }).then(({ items })=> { this.setState({ items }); }); } handleClick () => { this.props.openArticle(); } render() { return ( <div className='publication'> <h4>{this.props.name}</h4> <ul> {this.state.items.map(item => ( <li><a href={item.link} target='_blank' onClick={this.handleClick}>{item.title}</a></li> ))} </ul> </div> ); } }
The Parent:
export class Latest extends React.Component { constructor(props) { super(props); this.state = { totalReads: 0, articlesRead: [] }; } handleChange = () => { this.props.increaseTotal(); } increaseReads(titles) { this.setState({ totalReads: this.state.totalReads + 1, articlesRead: titles }) // Won't log correctly console.log(this.state.articlesRead); this.handleChange(); } render() { return ( <div className='container'> <Publication total={(titles) => {this.increaseReads(titles)}} name='Free Code Camp' api={'https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Fmedium.freecodecamp.org%2Ffeed%2F'}/> <Publication total={() => {this.increaseReads()}} name='Code Burst' api={'https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Fcodeburst.io%2Ffeed%2F'}/> <Publication total={() => {this.increaseReads()}} name='JavaScript Scene' api={'https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Fmedium.com%2Ffeed%2Fjavascript-scene%2F'}/> <Publication total={() => {this.increaseReads()}} name='Hacker Noon' api={'https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Fhackernoon.com%2Ffeed'}/> </div> ) } }
I'm sure it is something small, but any help would be greatly appreciated!
-
georgeperry about 6 yearsThanks! This worked! I added a callback function to the end of this.setState that revealed my state was in fact updating correctly