javascript - 在异步循环中设置 useState 挂钩
问题描述
我是 reactJs 的新手。
我试图在异步循环中连接结果,但是出了点问题。setState 没有正确保存,当我打印它时,我可以看到它是一个空数组,我想是因为里面有一个异步调用。
我该如何解决?请给我建议。
function App() {
const [data, setData] = useState({data:[]});
const handleChildSubmit = (data) => {
setData(data);
}
return (
<div>
<Form onChildSubmit={handleChildSubmit} />
<Results flights={data} />
</div>
);
}
const Form = ( {onChildSubmit} ) => {
const [dati, setDati] = useState([]);
const onFormSubmit = async (e) => {
e.preventDefault();
// Flights search Parameters
const data = new FormData(e.target);
const dateFrom = data.get('dateFrom');
const dateTo = data.get('dateTo');
const departureDay = data.get('day');
const placeFrom = data.get('placeFrom');
const placeTo = data.get('placeTo');
let dayDeparture;
const daysDeparture = getDayOfWeekArray(dateFrom,dateTo,departureDay);
// Loop of Fly Search in range time
for(let i=0; i < daysDeparture.length; i++){
dayDeparture = daysDeparture[i];
axios.get('https://api.skypicker.com/flights?flyFrom='+placeFrom+'&to='+placeTo+'&dateFrom='+dayDeparture+'&dateTo='+dayDeparture+'&partner=picky')
.then(res => {
setDati([...dati, res.data]);
onChildSubmit(dati);
})
.catch(function (error) {
console.log('error: '+error);
})
.finally(function () {
});
}
}
解决方案
问题是useState
这里为您dati
提供了具有特定值的变量。然后你的异步事情发生了,并被setDati()
多次调用,但dati
在重新呈现表单之前不会改变,然后你再次调用onFormSubmit
。
你有几个选择。
您只能将结果作为数组添加一次。
const results = []
for(let i=0; i < daysDeparture.length; i++){
dayDeparture = daysDeparture[i];
const res = await axios.get('https://api.skypicker.com/flights?flyFrom='+placeFrom+'&to='+placeTo+'&dateFrom='+dayDeparture+'&dateTo='+dayDeparture+'&partner=picky');
results.push(res.data);
}
// Add all results when all are fetched.
setDati([...dati, ...results])
或者useReducer
在您更改状态时可靠地为您提供最新版本的状态,因此您没有过时的数据。
// Something like...
function reducer(state, action) {
switch(action.type) {
case 'append':
return [...state, action.payload]
}
}
function YourComponent() {
const [dati, dispatch] = useReducer(reducer, [])
const onFormSubmit = async (e) => {
for(let i=0; i < daysDeparture.length; i++){
dayDeparture = daysDeparture[i];
const res = await axios.get('https://api.skypicker.com/flights?flyFrom='+placeFrom+'&to='+placeTo+'&dateFrom='+dayDeparture+'&dateTo='+dayDeparture+'&partner=picky')
dispatch({type: 'append', payload: res.data})
}
}
}
推荐阅读
- c - 在输入中找到最长单词时出现分段错误
- c# - 从另一个 Fragment 内部的 Fragment 调用方法
- angular - 将函数作为条件传递给 [ngClass] - Angular 7
- reactjs - 接受 prop 更新但不重新渲染的功能组件
- python - 无法在 ansible 中使用 ldap_entry(缺少必需的 'ldap' 模块(pip install python-ldap))
- javascript - 为什么 File->Print 和 window.print() 给我不同的输出?
- fortran - 使用 fortran PGI 编译器,为什么 real(.true.) 等于“-1.0”而 int(.true.) 等于“-1”?
- python - 我需要在 Kfold 循环中重置模型权重吗?
- cassandra-3.0 - Cassandra DB 中的时区
- python - Django REST Framework CURSOR 分页何时过期?