axios 如何等待在不同组件中进行的API调用完成?

yb3bgrhw  于 2023-04-20  发布在  iOS
关注(0)|答案(2)|浏览(134)

我正在创建一个draw.io类似于设计网站的www.example.com。我有一个用于保存设计的组件和一个用于编辑/设计师的组件。
在保存的设计组件中,我有一个“打开新文件”按钮,它可以发布新文件,然后导航到具有该文件ID的URL。

const openNewFile = () => {
    const fileObj = generateDefaultFileObj();
    axios.post(`http://localhost:8000/api/files/`, fileObj);
    navigate(`/file/${fileObj.fileID}`);
}

在设计编辑器组件中,当我尝试获取刚刚发布的文件时,我经常会得到一个错误,因为它试图在可用之前访问它。我知道我可以在导航到前一个组件中的文件之前等待API发布,但缺点是用户没有立即反馈正在执行某些操作。在任何事情发生之前都有半秒的延迟,我宁愿在编辑器组件中向用户呈现加载屏幕。

const Editor = () => {
    let { file } = useParams();
    const [isLoading, setLoading] = useState(true);
    const [fileData, setFileData] = useState();
    const [activeObjects, setActiveObjects] = useState([]);
    

    React.useEffect(() => {
        const filePromise = axios.get(`http://localhost:8000/api/files/${file}/`);
        const objectsPromise = axios.get(`http://localhost:8000/api/ro/file/${file}/`);

        Promise.all([filePromise, objectsPromise]).then(([fileResponse, objectsResponse]) => {
            setFileData(fileResponse.data);
            setActiveObjects(objectsResponse.data);
            setLoading(false);
        })

    }, []);

    if (isLoading) {
        return <div>Loading...</div>;
    }

    return (
        <div>Main Component</div>
    )
};

解决这个问题的最好办法是什么?

p4tfgftt

p4tfgftt1#

您可以像这样使用async/await来等待它结束所有调用

React.useEffect(async () => {
   ...
   await Promise.all(...)
   ...
})
92dk7w1h

92dk7w1h2#

以下是openNewFile的更新实现:

const openNewFile = async () => {
      const fileObj = generateDefaultFileObj();
      const response = await axios.post(`http://localhost:8000/api/files/`, fileObj);
      const newFile = response.data;
      navigate(`/file/${newFile.fileID}`);
      return newFile;
    };

下面是如何修改编辑器组件以使用返回的文件对象:

const Editor = () => {
  let { file } = useParams();
  const [isLoading, setLoading] = useState(true);
  const [fileData, setFileData] = useState();
  const [activeObjects, setActiveObjects] = useState([]);

  React.useEffect(() => {
    const getFileData = async () => {
      try {
        const fileResponse = await axios.get(`http://localhost:8000/api/files/${file}/`);
        const objectsResponse = await axios.get(`http://localhost:8000/api/ro/file/${file}/`);
        setFileData(fileResponse.data);
        setActiveObjects(objectsResponse.data);
      } catch (error) {
        console.error(error);
      } finally {
        setLoading(false);
      }
    };
    getFileData();
  }, [file]);

  if (isLoading) {
    return <div>Loading...</div>;
  }

  return <div>Main Component</div>;
};

相关问题