当我执行下面的代码时出现错误“无法读取 null 的属性(读取‘登录’)”,因为它到达了最后的 return 语句,它不应该因为我在返回之前已经检查了 bool 值.
import React, { useState, useEffect } from 'react';
const url = 'https://api.github.com/users/QuincyLarsn';
const MultipleReturns = () => {
const [isLoading, setIsLoading] = useState(true);
const [isError, setIsError] = useState(false);
const [user, setUser] = useState(null);
useEffect(() => {
fetch(url)
.then(data => {
if (data.status >= 200 && data.status <= 299)
return data.json();
else {
console.log("here");
setIsLoading(false);
setIsError(true);
console.log("here 2");
}
})
.then(result => {
setIsLoading(false);
setUser(result);
})
.catch(error => console.log(error))
}, []);
console.log(isError);
if (isLoading)
return <h2>Loading...</h2>
if (isError) {
return <h2>Error...</h2>
}
return <h2>{user.login}</h2>
};
export default MultipleReturns;
在上面的代码中,如果 setIsError(true) 放在 useEffect 中的 setIsLoading(false) 之前,那么一切正常,反之亦然,类似地,如果 url 是正确的,那么如果 setUser(result) 放在之前,一切都正常setIsLoading(false) 而不是相反。 我无法弄清楚为什么会这样。
最佳答案
React 不会从 fetch()
批处理状态更新。在事件监听器的情况下,它是批处理的。这是一个异步获取调用。
在此sandbox控制台,您可以看到在状态更新之间有一个渲染 - setIsLoading(false)
和 setIsError(true)
。
因此对于一个渲染周期:isLoading
为 false 并且 isError
也为 false。这将导致错误情况。
您可以使用 unstable_batchedUpdates 来强制执行批处理。
import { useEffect, useState } from "react";
import { unstable_batchedUpdates } from "react-dom";
import "./styles.css";
const url = "https://api.github.com/users/QuincyLarsn";
const App = () => {
const [isLoading, setIsLoading] = useState(true);
const [isError, setIsError] = useState(false);
const [user, setUser] = useState(null);
useEffect(() => {
fetch(url)
.then((data) => {
if (data.status >= 200 && data.status <= 299) return data.json();
else {
console.log("here");
unstable_batchedUpdates(() => {
setIsLoading(false);
setIsError(true);
});
console.log("here 2");
}
})
.then((result) => {
setIsLoading(false);
setUser(result);
})
.catch((error) => {
console.log(error);
});
}, []);
console.log("isError", isError);
if (isLoading) return <h2>Loading...</h2>;
if (isError) return <h2>Error...</h2>;
return <h2>{user.login}</h2>;
};
export default App;
Corrected Sandbox Link
https://stackoverflow.com/questions/70439180/
相关文章:
javascript - 数据到达 Controller 但不查看
c# - 检查ClassDeclarationSyntax是否实现了特定接口(interface)(
answer-set-programming - 使用答案集编程的 N 皇后问题
python - 如何在 ClientOSError : [Errno 104] Connectio
c# - 如何同步运行异步枚举器方法并将其存储为 IEnumerable?
python - 如何像在 C# 中一样同步运行 Python 协程,直到第一次等待?