The value of this.state.topText and this.state.bottomText is always one change behind. Eg 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
import React from "react";
import MemeGenerator from "./MemeGenerator"
import "./styles.css";
class App extends React.Component {
constructor() {
super();
this.state = {
topText:"",
bottomText: "",
imgs: [],
imgUrl:""
};
this.handleChange=this.handleChange.bind(this)
this.handleClick=this.handleClick.bind(this)
}
handleChange(event) {
const {name, value} = event.target
this.setState((prevstate) => ({
...prevstate,
[name]: value
}));
document.getElementById('tt').innerHTML=this.state.topText;
document.getElementById('bt').innerHTML=this.state.bottomText;
}
handleClick(target){
const imgNum=this.state.imgs.length;
const randNum=Math.floor(Math.random()*imgNum)
this.setState((prevState)=>{
return {imgUrl: prevState.imgs[randNum].url }
})
}
componentDidMount(){
fetch('https://api.imgflip.com/get_memes')
.then((response)=> response.json())
.then((data)=>{
const randImg=data.data.memes
this.setState(()=>{
return{imgs: randImg}
})
})
}
render() {
return (
<MemeGenerator
handleChange={this.handleChange}
handleClick={this.handleClick}
topText={this.state.topText}
bottomText={this.state.bottomText}
imgUrl={this.state.imgUrl}
/>
);
}
}
export default App;
MemeGenerator.js
import React from "react"
function MemeGenerator(props){
return(
<div className="App">
<h1>Meme Generator</h1>
<input
type="text"
name="topText"
value={props.topText}
onChange={(event)=>props.handleChange(event)}
/>
<input
type="text"
value={props.bottomText}
name="bottomText"
onChange={(event)=>props.handleChange(event)}
/>
<button onClick={(event)=>props.handleClick(event.target)}>Gen</button>
<img
src={props.imgUrl}
alt=""
width="300"
/>
<p id="tt"></p>
<p id="bt"></p>
</div>
)
}
export default MemeGenerator
setState
accepts a callback as a second param which will be executed right after the state change.
handleChange(event) {
const {name, value} = event.target
this.setState({ [name]: value }, () => {
document.getElementById('tt').innerHTML=this.state.topText;
document.getElementById('bt').innerHTML=this.state.bottomText;
});
}
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
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.