我试图在UseEffect中获取多个端点,并根据它的结果显示UI上的数据(头像,用户名等)
问题是,在useEffect
内部的fetch()
调用中收到的数据实际上返回了正确的数据,但当试图在ui代码中访问它时,它不会显示。
正如你在我的代码中看到的,我有isLoading状态,但我觉得then
操作并没有真正等到响应存在。加载屏幕将显示0.5秒,但当正常屏幕弹出时,用户名,头像等为空。
那么我怎样才能让UI等待,直到useEffect
完全加载数据,然后显示它?
UserProfile.tsx
React.useEffect(() => {
AsyncStorage.getItem(LOGGED_IN_USER).then((userSteamID) =>
fetch(USER_PROFILE + userSteamID)
.then((response) => response.json())
.then((json) => json.steamId)
.then((steamId) => {
fetch(USER_INVENTORY + steamId)
.then((response) => response.json())
.then((json) => {
console.log(json);
setProfileInfo(json);
setSteamID(json.steamId);
setInventoryValue(json.value);
})
.catch((err) => alert(err))
.finally(() => setLoading(false));
})
);
}, []);
尝试稍后使用:
if (loading) {
return (
<View
style={{
height: "100%",
justifyContent: "center",
backgroundColor: Colors.dark.background,
}}
>
<ActivityIndicator
size="large"
style={{ backgroundColor: Colors.dark.background }}
/>
<Text
style={{
color: Colors.dark.text,
marginTop: 10,
alignSelf: "center",
}}
>
retrieving userdata...
</Text>
</View>
);
} else {
return (
<Text>{inventoryValue}</Text> // avatar, etc. wont work as well
)
我从一个LoginScreen.tsx
导航到它,像这样:
onPress={async () => {
let result = await startAuth();
if (result.type == "success") {
setLoggedInUser(result.steamID);
console.log("ID: " + result.steamID);
navigation.navigate("UserProfile");
}
创建承诺链
React.useEffect(() => {
AsyncStorage.getItem(LOGGED_IN_USER).then((userSteamID) =>
fetch(USER_PROFILE + userSteamID)
.then((response) => response.json())
.then((json) => json.steamId)
.then((steamId) => fetch(USER_INVENTORY + steamId))
.then((response) => response.json())
.then((json) => {
setProfileInfo(json);
// This can be avoided, already available in profileInfo
setSteamID(json.steamId);
setInventoryValue(json.value);
})
.catch((err) => alert(err))
.finally(() => setLoading(false))
);
}, []);
异步/等待
React.useEffect(() => {
const init = async () => {
try {
const userSteamID = await AsyncStorage.getItem(LOGGED_IN_USER);
const { steamId } = await fetch(USER_PROFILE + userSteamID).then((r) =>
r.json()
);
const json = await fetch(USER_INVENTORY + steamId).then((r) => r.json());
setProfileInfo(json);
// This can be avoided, already available in profileInfo
setSteamID(json.steamId);
setInventoryValue(json.value);
} catch (error) {
alert(error);
} finally {
setLoading(false);
}
};
init();
}, []);