【发布时间】:2021-08-29 02:25:36
【问题描述】:
const { Button } = require("@material-ui/core");
const { useState } = require("react");
const Test = () => {
const [loading, setLoading] = useState(false);
const [todos, setTodos] = useState([]);
const [users, setUsers] = useState([]);
const getTodos = async () => {
setLoading(true);
const res = await fetch("https://jsonplaceholder.typicode.com/todos");
const resData = await res.json();
setTodos(resData);
setLoading(false);
};
const getUsers = async () => {
setTodos([]);
setLoading(true);
console.log(loading)
const res = await fetch("https://jsonplaceholder.typicode.com/users");
const resData = await res.json();
setUsers(resData);
setLoading(false);
};
return (
<div>
<Button
color="primary"
variant="contained"
disabled={loading}
onClick={getTodos}
>
Get Todos
</Button>
<Button
color="primary"
variant="contained"
disabled={loading}
onClick={getUsers}
>
Get Users
</Button>
{todos.map((item) => (
<div>{JSON.stringify(item)}</div>
))}
{users.map((item) => (
<div>{JSON.stringify(item)}</div>
))}
</div>
);
};
export default Test;
由于 setLoading 是异步的并且不返回任何承诺,有没有办法成功设置加载状态,然后最终获取数据不使用具有加载依赖关系的 useEffect。我认为加载状态使用 useEffect 会变得复杂,因为加载状态用于多个 api 调用。
【问题讨论】:
-
我看不出当前的实现是如何工作的。你可以先
setLoading再打电话给getUsers? -
如果我们以
getTodos()为例,setLoading(true)和fetch()可能会被异步调用,而不是一个接一个地调用。我实际上希望它是同步的。 -
您所做的是正确的,您只需将待办事项设置为
response并在获取后加载到false,设置状态为async,但不应该在您的情况下造成问题。如果你想在设置完待办事项后设置加载,你将不得不使用useEffect,但是你的代码看起来不错。 -
所以如果
setLoading()需要时间,用户将能够在组件重新渲染之前多次单击该按钮。我有点不希望这种情况发生。
标签: reactjs react-hooks