reactjs 如何使用React中的setState处理第二个请求依赖于第一个请求的两个get请求?

4szc88ey  于 2022-12-29  发布在  React
关注(0)|答案(3)|浏览(235)

我是React的新手,我知道useState不会立即得到反映。
在我的第一个get请求中,我基于URL而不是pageID获取页面信息,因为我试图在共享页面时自定义URL,而不是像这样:http://localhost:3000/pages/:pageId,所以它变成了http://localhost:3000/pages/DT/:url。在第二个get请求中,我基于pageID获取模板来呈现模板(房屋)。
因为我没有使用pageID,所以我不能使用useParams来获取值。相反,我尝试在第一个get请求(setPageId(res.data.page.id))中这样设置pageID
但是,由于我无法从第一个get请求中获取pageID,因此第二个请求变为http://localhost:8080/api/RE/template/null
我尝试过localStorage.setItem("pageId", res.data.page.id),它可以工作,但我不想每次都使用本地存储设置或删除。我还尝试了2秒的setTimeout,但仍然不起作用。在useEffect中,我添加了pageID作为依赖项,但仍然没有任何结果。我还尝试了使用Promise,后来也这样做了,但pageID也返回null。

useEffect(() => {
    getCustomUrl()
      .then(() => {
        getTemplates();
      })
      .catch((err) => {
        console.log(err);
      });
  }, []);

我想知道的是,处理两个相互依赖的请求的最佳方法是什么?

const [loadedSharePages, setLoadedSharePages] = useState(null);
  const [loadedTemplates, setLoadedTemplates] = useState([]);
  const [pageId, setPageId] = useState(null);

  const url = useParams().url;

  const getCustomUrl = async () => {
    await axios({
      method: "GET",
      url: `http://localhost:8080/api/pages/DT/${url}`,
      headers: {
        Authorization: "Bearer " + localStorage.getItem("token"),
      },
    })
      .then((res) => {
        console.log("Respond from the request getCusomUrl-->", res);
        setLoadedSharePages(res.data.page);
        setPageId(res.data.page.id);
      })
      .catch((err) => {
        console.log(err);
      });

    console.log("Shared page --> ", loadedSharePages);
    console.log("pageid: ", pageId);
  };

  const getTemplates = async () => {
    await axios({
      method: "GET",
      url: `http://localhost:8080/api/RE/template/${pageId}`,
      headers: {
        "Content-Type": "multipart/form-data",
        Authorization: "Bearer " + localStorage.getItem("token"),
      },
    })
      .then((res) => {
        console.log("Respond from the request -->", res);
        setLoadedTemplates(res.data.templates);
        console.log("Res.data.templates -->", res.data.templates);
      })
      .catch((err) => {
        console.log(err);
      });

    console.log("Loaded Templates --> ", loadedTemplates);
  };

  useEffect(() => {
    getCustomUrl();
    getTemplates();
  }, []);
ivqmmu1c

ivqmmu1c1#

为每个依赖于前一个请求的请求做单独的效果。这是一个简单的解决方案。
然后你可以考虑如何为它定制一个钩子等等。
通过将效果添加到效果参数的括号中,可以将效果设置为依赖于某个状态。
例如:(如伪代码)

useEffect(()=> ...getTheFirstData. then(//update the state1) ,[stateStartAction]);

//will happen when state1 has changed
useEffect(()=> ...getTheSecondData. then(//update the next state) ,[state1]);

//And so on what you need

在代码上通过以下方式触发效果:

setStartAction(!stateStartAction);
2lpgd968

2lpgd9682#

我建议把实际的API请求提取到一些更独立的带有参数的东西上,而不需要设置里面的状态,这样你就可以把那些函数移到一个单独的api.js文件中(例如),你可以在以后重用它们,保持实际组件代码的清晰。
此方法可能有助于您:

const getCustomUrl = (url) => {
  return axios({
    method: "GET",
    url: `http://localhost:8080/api/pages/DT/${url}`,
    headers: {
      Authorization: "Bearer " + localStorage.getItem("token")
    }
  }).then((res) => {
    console.log("Respond from the request getCusomUrl-->", res);
    return res.data;
  });
};

const getTemplates = (pageId) => {
  return axios({
    method: "GET",
    url: `http://localhost:8080/api/RE/template/${pageId}`,
    headers: {
      "Content-Type": "multipart/form-data",
      Authorization: "Bearer " + localStorage.getItem("token")
    }
  }).then((res) => {
    console.log("Respond from the request -->", res);
    return res.data;
  });
};

useEffect(() => {
  async function fetchMyAPI() {
    const getCustomUrlData = await getCustomUrl(url);
    const getTemplatesData = await getTemplates(getCustomUrlData.page.id);
    
    setLoadedSharePages(getCustomUrlData.page);
    setPageId(getCustomUrlData.page.id);
    setLoadedTemplates(getTemplatesData.templates);
  }
  fetchMyAPI().catch(console.error);
}, []);
abithluo

abithluo3#

这个解决了我的问题。

const getCustomUrl = async () => {
    try {
      const res = await axios({
        method: "GET",
        url: `http://localhost:8080/api/pages/DT/${url}`,
        headers: {
          Authorization: "Bearer " + localStorage.getItem("token"),
        },
      });

      setLoadedSharePages(res.data.page);
      setPageId(res.data.page.id);

      return res.data.page.id;
    } catch (err) {
      console.log(err);
    }
  };

  const getTemplates = async () => {
    try {
      const pageId = await getCustomUrl();
      const res = await axios({
        method: "GET",
        url: `http://localhost:8080/api/RE/template/${pageId}`,
        headers: {
          "Content-Type": "multipart/form-data",
          Authorization: "Bearer " + localStorage.getItem("token"),
        },
      });

      setLoadedTemplates(res.data.templates);
      console.log("Res.data.templates -->", res.data.templates);
    } catch (err) {
      console.log(err);
    }
  };

 useEffect(() => {
    getTemplates();
  }, []);

相关问题