我正在尝试破解状态未更新的特定螺母。
我有一个通过Axios调用NASA api的函数,它工作正常。当前datePicked
状态默认为空,这意味着GET请求默认为当前日期。我要添加功能以生成随机日期(功能onRandomDateClick
),一切正常。
然后,我想用生成的日期更新datePicked
的状态,然后运行保存axios请求的onImageGet
函数。
初始状态
class Photo extends Component {
state = {
apiUrl: 'XXXXXXXX',
apiKey: 'XXXXXXXX',
image: null,
imgChecked: false,
datePicked: ""
};
生成随机日期,记录变量和状态。状态当前显示为空白。 this.setState无法正常工作。
onRandomDateClick = (e) => {
function randomDate(start, end) {
return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
}
let randomDateResult = randomDate(new Date(2012, 0, 1), new Date())
let datePicked = randomDateResult.toISOString().slice(0,10);
this.setState({datePicked})
console.log("variable is " + datePicked);
console.log("state is " + this.state.datePicked);
this.onImageGet();
}
此处有状态的Axios呼叫
onImageGet = e => {
axios.get(`${this.state.apiUrl}?api_key=${this.state.apiKey}&date=${this.state.datePicked}`)
//response always starts res.data
.then(res => {
const image = res.data;
this.setState({ image })
})
this.setState({imgChecked: true})
}
render() {
...blah blah...
return (
<div className="photo">
... blah blah blah ...
</div>
);
}
}
答案 0 :(得分:1)
问题在于setState
是异步的,因此在设置状态后立即调用onImageGet
时,状态尚未更新,您可以访问前一个状态。
状态更新后,可以使用setState
支持的回调方法。
this.setState({datePicked}, this.onImageGet)
或更常见的模式是检查componentDidUpdate
中的相关更改,然后在其中调用this.onImageGet
。
class Photo extends Component {
state = {
apiUrl: 'XXXXXXXX',
apiKey: 'XXXXXXXX',
image: null,
imgChecked: false,
datePicked: ""
};
onRandomDateClick = (e) => {
function randomDate(start, end) {
return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
}
let randomDateResult = randomDate(new Date(2012, 0, 1), new Date())
let datePicked = randomDateResult.toISOString().slice(0,10);
this.setState({datePicked})
console.log("variable is " + datePicked);
console.log("state is " + this.state.datePicked);
}
onImageGet = e => {
axios.get(`${this.state.apiUrl}?api_key=${this.state.apiKey}&date=${this.state.datePicked}`)
//response always starts res.data
.then(res => {
const image = res.data;
this.setState({ image })
})
this.setState({imgChecked: true})
}
componentDidUpdate(prevProps, prevState){
if (prevState.datePicked !== this.state.datePicked){
this.onImageGet();
}
}
render() {
...blah blah...
return (
<div className="photo">
... blah blah blah ...
</div>
);
}
}
答案 1 :(得分:1)
JS正在为HTTP调用异步工作。因为React setState
是异步的。您应该这样做。
onRandomDateClick = (e) => {
function randomDate(start, end) {
return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
}
let randomDateResult = randomDate(new Date(2012, 0, 1), new Date())
let datePicked = randomDateResult.toISOString().slice(0,10);
this.setState({datePicked},() => {
this.onImageGet();
})
}
onImageGet = e => {
axios.get(`${this.state.apiUrl}?api_key=${this.state.apiKey}&date=${this.state.datePicked}`)
//response always starts res.data
.then(res => {
const image = res.data;
this.setState({ image, imgChecked: true })
})
}
render() {
...blah blah...
return (
<div className="photo">
... blah blah blah ...
</div>
);
}
}