在 useEffect 中调用 useFetch 钩子

时间:2021-05-28 06:14:23

标签: javascript reactjs react-hooks

我发现了一个非常 interesting hook 并且我想在 useEffect 中使用这个钩子(它违反规则)

const useFetch = (url, options) => {
  const [response, setResponse] = React.useState(null);
  const [error, setError] = React.useState(null);
  React.useEffect(() => {
    const fetchData = async () => {
      try {
        const res = await fetch(url, options);
        const json = await res.json();
        setResponse(json);
      } catch (error) {
        setError(error);
      }
    };
    fetchData();
  }, []);
  return { response, error };
};

function App() {
  const res = useFetch("example.com", {});

   useEffect(() => {
       // use the hook and make a secondary request 
   }, [])

为了支持这一点,我需要做哪些修改? AFAIK 钩子不能在 useEffect 内部调用

也许是一个新的参数,它会 setUrl 并再次运行它?

2 个答案:

答案 0 :(得分:0)

您不能有条件地调用 useFetch,也不能在任何回调(即 useEffect 回调)中调用它(请参阅 rules of hooks),但您可以利用以下事实钩子在每次渲染时以相同的顺序调用。执行条件测试并设置传递给第二个 useFetch 挂钩的 URL。在发出请求之前更新 useFetch 钩子以检查真实的 url

const useFetch = (url, options) => {
  const [response, setResponse] = React.useState(null);
  const [error, setError] = React.useState(null);
  React.useEffect(() => {
    const fetchData = async () => {
      try {
        const res = await fetch(url, options);
        const json = await res.json();
        setResponse(json);
      } catch (error) {
        setError(error);
      }
    };
    url && fetchData();
  }, []);
  return { response, error };
};

...

function App() {
  const res = useFetch("example.com", {});

  let url = "";
  if (someCondition) {
    let url = ""example2.com"";
  }
  const res2 = useFetch("example.com", {});

答案 1 :(得分:0)

当某些状态或变量发生变化时,您似乎想在钩子中执行获取请求。

您不能有条件地调用一个钩子,也不能根据文档中提到的 rules of hooks 在另一个钩子中执行它。

为了做你想做的事,你可以修改你的自定义钩子来接受一个数组作为你传递给它里面的 useEffect 的依赖项,当任何依赖项发生变化时它会调用 api

const useFetch = (url, options, deps = []) => {
  const [response, setResponse] = React.useState(null);
  const [error, setError] = React.useState(null);
  React.useEffect(() => {
    const fetchData = async () => {
      try {
        const res = await fetch(url, options);
        const json = await res.json();
        setResponse(json);
      } catch (error) {
        setError(error);
      }
    };
    url && fetchData();
  }, deps);
  return { response, error };
};

并像使用它一样

function App() {
  const res = useFetch("example.com", {}, [someVariable]);

  ...
}