[英]React State Not Updating on First click and Component Not Rendering
retrieveInTransit()
is the click handler. retrieveInTransit()
是单击处理程序。 An API call retrieves data and returns an array of objects into the new state object in the setState()
function. API调用检索数据并将对象数组返回到setState()
函数中的新状态对象中。 The first click logs an empty array for the pumps
property. 第一次单击将为pumps
属性记录一个空数组。 If I click it again, I get the populated array of pumps
. 如果再次单击它,将得到填充的pumps
阵列。 Why do I have to click twice? 为什么我必须单击两次? The Equipment component
does not render even though the log in the render()
function returns the correct array of pumps which is passed in as a prop for the Equipment component
. 即使render()
函数中的日志返回正确的泵数组, Equipment component
也不会渲染,该数组作为Equipment component
的prop传入。 I am at a loss on this and any help would be appreciated. 我对此不知所措,任何帮助将不胜感激。
import React, { Component } from 'react';
import {ListGroup} from 'reactstrap';
import Equipment from './Equipment';
class Transit extends Component {
constructor(props) {
super(props);
this.state = {
pending: false,
pumps: []
};
}
handleCancelClick = (index) => {
this.setState((prevState) =>
prevState.pumps[index].isCancelled = !prevState.pumps[index].isCancelled
);
this.setState((prevState) => {
prevState.pumps.every((equipment) => equipment.isCancelled === false)
? prevState.pending = false: prevState.pending = true
}
)};
populate_transit = () => {
let pumpArray = [];
fetch('http://192.168.86.26:8000/api/v1/transit_list', {mode: 'cors'})
.then(response => response.json())
.then(MyJson => MyJson.map((entry) =>{
if (document.getElementsByClassName('title')[0].innerText.toLowerCase().includes(entry.transferfrom)) {
pumpArray.push(
{
unitnumber: entry.unitnumber,
id: entry.id,
message: entry.unitnumber + ' was moved to ' + entry.transferto,
isCancelled: false
});
}}));
return pumpArray
};
cancelTransit = () => {
let cancelled = this.state.pumps.filter((movement) => movement.isCancelled);
let cancelledId = cancelled.map((object) => object.id);
fetch('http://192.168.86.26:8000/api/v1/transit_list/', {
method:'POST',
mode: 'cors',
body: JSON.stringify(cancelledId),
headers:{
'Content-Type': 'application/json'
}
}
);
this.populate_transit()
};
retrieveInTransit = () => {
if (this.state.pending) {
this.setState({
pending: false,
pumps: this.cancelTransit()
}, console.log(this.state))} else {
this.setState({
pending: false,
pumps: this.populate_transit()
}, console.log(this.state))
}
};
render() {
console.log(this.state.pumps);
return (
<ListGroup>
<Equipment transitequipment={this.state.pumps} cancelClick={this.handleCancelClick}/>
<button className='btn btn-dark' onClick={this.retrieveInTransit}>
{this.state.pending ? 'Submit Cancellations': 'Refresh'}
</button>
</ListGroup>
);
}
}
export default Transit;
populate_transit = () => {
let pumpArray = [];
fetch('http://192.168.86.26:8000/api/v1/transit_list', {mode: 'cors'})
.then(response => response.json())
.then(MyJson => MyJson.map((entry) =>{
if (document.getElementsByClassName('title')[0].innerText.toLowerCase().includes(entry.transferfrom)) {
pumpArray.push(
{
unitnumber: entry.unitnumber,
id: entry.id,
message: entry.unitnumber + ' was moved to ' + entry.transferto,
isCancelled: false
});
}}));
return pumpArray};
So, In the code above, you are returning pumpArray
outside of the fetch
call. 因此,在上面的代码中,您将在fetch
调用之外返回pumpArray
。 Since fetch
takes time to call
the api
and resolve
the promise, the current value of your pumpArray
= []
that's why you get the empty array at first. 由于fetch
需要花费一些时间来call
api
和resolve
promise,因此pumpArray
的当前值= []
,这就是为什么首先获取空数组的原因。 On the next click
promise
is already resolved
so you get your pumpedArray
. next click
promise
已经resolved
因此您得到了pumpedArray
。 In order to fix this, move the pumpArray
inside then
. 为了解决此问题,请在then
将pumpArray
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.