我不知道如何命名这个问题,请随意编辑。
我正在使用一个提供项目(与登录名/密码唯一相关)和与这些项目的任务相关的状态列表的 API。它有两条路线:
login
和一个 password
并返回其 ID 和名称:{idProject: string, nome: string}
idProject
并返回其状态数组[{idStatus: string, area: string, descricao: string}]
我知道混合语言而不使用令牌是一种非常糟糕的做法,但我不是编写后端的人,我只是在使用它。由于我使用的是打字稿,我决定不翻译变量名称,否则类型会混乱,我很抱歉。
我创建了一个 services.tsx
来使用它:
import axios from "axios";
const api = axios.create({
baseURL: "", // omitted for safety reasons
});
export const getUserPromise = async (login: string, password: string) => {
const userPromise = api.get(`/projetos?login=${login}&senha=${password}`);
return userPromise;
};
export const getAllStatusPromise = async (idProjeto: string) => {
const AllStatusPromise = api.get(`/projetos/${idProjeto}/statusAreas`);
return AllStatusPromise;
};
我的 App.tsx
定义了函数 getUser()
和 getAllStatus()
,用于处理 promise 并将它们存储在 user
和 allStatus
状态。
它还定义了一个异步 getRequests()
函数,该函数在 useEffect()
上用于 await
调用 getUser()
和 getAllStatus()
。
它还在 html 上打印结果:
import React, { useEffect, useState } from "react";
import { getUserPromise, getAllStatusPromise } from "./services";
const App: React.FC = () => {
const [user, setUser] = useState({
idProjeto: "0000",
nome: "Fallback User",
});
const [allStatus, setAllStatus] = useState([
{
idStatus: "0000",
area: "Fallback AllStatus",
descricao: "Fallback allStatus",
},
]);
useEffect(() => {
getRequests();
}, []);
const getRequests = async () => {
const mocked_login = ""; // Omitted for safety reasons
const mocked_password = ""; // Omitted for safety reasons
await getUser(mocked_login, mocked_password);
await getAllStatus(user.idProjeto);
};
const getUser = async (login: string, password: string) => {
try {
const userPromise = await getUserPromise(login, password);
const user = userPromise.data;
setUser(user);
} catch (error) {
console.log(error);
}
};
const getAllStatus = async (idProjeto: string) => {
try {
const allStatusPromise = await getAllStatusPromise(idProjeto);
const allStatus = allStatusPromise.data;
setAllStatus(allStatus);
} catch (error) {
console.log(error);
}
};
return (
<div>
<p>
user.nome: {user.nome} | user.idProjeto: {user.idProjeto}
</p>
<p>Number of status: {allStatus.length}</p>
{allStatus.map((status) => {
return (
<ul>
Status:
<li>status.area: {status.area}</li>
<li>status.descricao: {status.descricao}</li>
<li>status.idStatus: {status.idStatus}</li>
</ul>
);
})}
</div>
);
};
export default App;
我使用 user
状态作为 getAllStatus()
的参数。
这段代码有效:
user
在呈现页面时已成功设置:与我的模拟登录名和密码相关的用户具有 projectId === 12345
。
但是,allStatus
没有预期值。它请求了后备 projectId
0000,它在 api 上返回 63 状态。但是,projecId
12345 没有 63 状态。它只有 5 个。
这意味着我的异步调用有问题。调用 user.projectId
时,1245
状态未设置为 getAllStatus()
。但是当页面呈现时,这就是呈现用户工作但对 getAllStatus
的顺序调用不工作的原因。
如何强制 getAllStatus()
等待 getUser()
中的状态更改完成?
答案 0 :(得分:1)
useState 有时不会立即改变状态。在您的情况下,您可以返回用户并在您的 getRequests 函数中获取它。
const getRequests = async () => {
const mocked_login = ""; // Omitted for safety reasons
const mocked_password = ""; // Omitted for safety reasons
const user = await getUser(mocked_login, mocked_password); // get the returned user
await getAllStatus(user.idProjeto);
};
const getUser = async (login: string, password: string) => {
try {
const userPromise = await getUserPromise(login, password);
const user = userPromise.data;
setUser(user);
return user; // return it here
} catch (error) {
console.log(error);
}
};