The value of this.state.topText and this.state.bottomText is always one change behind. E.g if I type 1234 in topText’s input box, the value of this.state.topText would be 123. The react docs say to fix asynchronous updates we should use the form of setState() that accepts a function rather than an object. I have done that and the value of setState is still lagging. How do I fix the setState() in handleChange()?
App.js
JavaScript
x
66
66
1
import React from "react";
2
import MemeGenerator from "./MemeGenerator"
3
import "./styles.css";
4
5
class App extends React.Component {
6
constructor() {
7
super();
8
this.state = {
9
topText:"",
10
bottomText: "",
11
imgs: [],
12
imgUrl:""
13
};
14
this.handleChange=this.handleChange.bind(this)
15
this.handleClick=this.handleClick.bind(this)
16
}
17
18
handleChange(event) {
19
const {name, value} = event.target
20
this.setState((prevstate) => ({
21
prevstate,
22
[name]: value
23
}));
24
document.getElementById('tt').innerHTML=this.state.topText;
25
document.getElementById('bt').innerHTML=this.state.bottomText;
26
27
}
28
29
handleClick(target){
30
const imgNum=this.state.imgs.length;
31
const randNum=Math.floor(Math.random()*imgNum)
32
this.setState((prevState)=>{
33
return {imgUrl: prevState.imgs[randNum].url }
34
})
35
36
}
37
38
componentDidMount(){
39
fetch('https://api.imgflip.com/get_memes')
40
.then((response)=> response.json())
41
.then((data)=>{
42
const randImg=data.data.memes
43
this.setState(()=>{
44
return{imgs: randImg}
45
})
46
})
47
}
48
49
render() {
50
return (
51
<MemeGenerator
52
handleChange={this.handleChange}
53
handleClick={this.handleClick}
54
topText={this.state.topText}
55
bottomText={this.state.bottomText}
56
imgUrl={this.state.imgUrl}
57
58
/>
59
);
60
}
61
}
62
63
export default App;
64
65
66
MemeGenerator.js
JavaScript
1
36
36
1
import React from "react"
2
3
function MemeGenerator(props){
4
return(
5
<div className="App">
6
<h1>Meme Generator</h1>
7
<input
8
type="text"
9
name="topText"
10
value={props.topText}
11
onChange={(event)=>props.handleChange(event)}
12
/>
13
14
<input
15
type="text"
16
value={props.bottomText}
17
name="bottomText"
18
onChange={(event)=>props.handleChange(event)}
19
/>
20
21
<button onClick={(event)=>props.handleClick(event.target)}>Gen</button>
22
23
<img
24
src={props.imgUrl}
25
alt=""
26
width="300"
27
/>
28
29
<p id="tt"></p>
30
<p id="bt"></p>
31
</div>
32
)
33
}
34
35
export default MemeGenerator
36
Advertisement
Answer
setState
accepts a callback as a second param which will be executed right after the state change.
JavaScript
1
8
1
handleChange(event) {
2
const {name, value} = event.target
3
this.setState({ [name]: value }, () => {
4
document.getElementById('tt').innerHTML=this.state.topText;
5
document.getElementById('bt').innerHTML=this.state.bottomText;
6
});
7
}
8
Please check the below:
https://medium.learnreact.com/setstate-takes-a-callback-1f71ad5d2296 https://upmostly.com/tutorials/how-to-use-the-setstate-callback-in-react