【发布时间】:2020-07-17 01:24:12
【问题描述】:
setLoading 在获取所有数据之前被调用。如何确保仅在获取数据的 for 循环完成后才调用 setLoading?将异步数据与非异步数据结合起来甚至是可取的吗?我想要实现的是呈现一个时间线,每个事件都伴随着它们各自的方向(这是异步数据)
const Schedule = (props) => {
const [events, setEvents] = React.useState([]);
const [visible, setVisible] = React.useState(false);
const [unsatisfied, setUnsatisfied] = React.useState("");
const [timingsArray, setTimingsArray] = React.useState([]);
const [isLoading, setLoading] = React.useState(true);
React.useEffect(() => {
directionsArray(props.initRoutes, props.timings, props.data);
}, []);
const directionsArray = async (allRoutes, timings, data) => {
let result = [];
for (let i = 0; i < allRoutes.length - 1; i++) {
let obj = { distance: "", duration: "", steps: [] };
let steps = [];
let distance = "";
let duration = "";
let origin =
typeof allRoutes[i] === "object"
? allRoutes[i].lat + "," + allRoutes[i].long
: allRoutes[i];
let destination = allRoutes[i + 1];
try {
let resp = await fetch(
"https://maps.googleapis.com/maps/api/directions/json?origin=" +
origin +
"&destination=" +
destination +
"&key=" +
GOOGLE_MAPS_API_KEY +
"&mode=transit®ion=sg"
);
//console.log(JSON.stringify(await resp.json()));
let data = (await resp.json())["routes"][0]["legs"][0];
let response = data["steps"];
distance = data["distance"]["text"];
duration = data["duration"]["text"];
for (let j = 0; j < response.length; j++) {
steps.push(await routeFormatter(await response[j]));
}
} catch (err) {
console.log(err);
}
obj.steps = steps;
obj.distance = distance;
obj.duration = duration;
result.push(obj);
}
let updatedTimings = merge(timings, result);
let combinedData = eventsWithDirections(updatedTimings, data, result);
setTimingsArray(updatedTimings);
setEvents(combinedData);
setLoading(false);
};
if (isLoading) {
return (
<View
style={{
flex: 1,
alignContent: "center",
justifyContent: "center",
}}
>
<ActivityIndicator
style={{ alignSelf: "center" }}
size="large"
/>
</View>
);
} else {
return (
<View style={styles.container}>
<View style={styles.body}>
<Modal animated visible={visible} animationType="fade">
<ActionOptions
onReselect={onReselect}
onClose={onClose}
unsatisfied={unsatisfied}
events={props.allEvents}
genres={props.genres}
newTimeChange={newTimeChange}
filters={props.filters}
/>
</Modal>
<Timeline
onEventPress={(event) => onEventPress(event)}
data={events}
timeStyle={{
textAlign: "center",
backgroundColor: "#cc5327",
color: "white",
padding: 5,
borderRadius: 13,
}}
/>
</View>
<View style={styles.footer}>{renderProceedButton()}</View>
</View>
);
}
};
【问题讨论】:
-
不清楚这里有什么问题。在所有这些 set 调用 after 之前,似乎什么都不会发生。
setLoading在数组准备好之前被调用是什么意思? -
@JaredSmith 我将获取的数据推送到结果数组中,然后我想使用该数组来呈现我的组件,但是在数组具有来自 API 调用的数据之前调用 setLoading组件什么也不渲染。
-
再说一次,我不知道是否存在语言障碍或概念障碍或两者兼而有之,但这根本不是这样的。
-
尝试在
setEvents(combinedData);之前记录combinedData 以确保它是您所期望的 -
@RuiFeng 你可以使用Promise.all
标签: javascript reactjs react-native async-await