I'm trying to pass an array (titles) from a child ponent 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: []
};
}
ponentDidMount() {
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={'.json?rss_url=https%3A%2F%2Fmedium.freecodecamp%2Ffeed%2F'}/>
<Publication total={() => {this.increaseReads()}} name='Code Burst' api={'.json?rss_url=https%3A%2F%2Fcodeburst.io%2Ffeed%2F'}/>
<Publication total={() => {this.increaseReads()}} name='JavaScript Scene' api={'.json?rss_url=https%3A%2F%2Fmedium%2Ffeed%2Fjavascript-scene%2F'}/>
<Publication total={() => {this.increaseReads()}} name='Hacker Noon' api={'.json?rss_url=https%3A%2F%2Fhackernoon%2Ffeed'}/>
</div>
)
}
}
I'm sure it is something small, but any help would be greatly appreciated!
I'm trying to pass an array (titles) from a child ponent 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: []
};
}
ponentDidMount() {
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./v1/api.json?rss_url=https%3A%2F%2Fmedium.freecodecamp%2Ffeed%2F'}/>
<Publication total={() => {this.increaseReads()}} name='Code Burst' api={'https://api.rss2json./v1/api.json?rss_url=https%3A%2F%2Fcodeburst.io%2Ffeed%2F'}/>
<Publication total={() => {this.increaseReads()}} name='JavaScript Scene' api={'https://api.rss2json./v1/api.json?rss_url=https%3A%2F%2Fmedium.%2Ffeed%2Fjavascript-scene%2F'}/>
<Publication total={() => {this.increaseReads()}} name='Hacker Noon' api={'https://api.rss2json./v1/api.json?rss_url=https%3A%2F%2Fhackernoon.%2Ffeed'}/>
</div>
)
}
}
I'm sure it is something small, but any help would be greatly appreciated!
Share Improve this question edited Jul 2, 2020 at 11:52 georgeperry asked Feb 12, 2018 at 16:22 georgeperrygeorgeperry 2042 gold badges5 silver badges14 bronze badges 1- there is a way to do this if you pass a callback function as a prop, but first, why is one publication getting titles as an argument and the rest not? – Eric Hasselbring Commented Feb 12, 2018 at 16:42
1 Answer
Reset to default 6The 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 pleted.
Notice how in the console.log
output, we can see the old
and new
state values.