React Custom Fetch Hook,强制重新获取

React Custom Fetch Hook, force Refetch

我正在尝试生成一个 CustomHook,它接收一个负责执行查询的函数。 CustomHook 应该执行查询并 return 它。

问题: 当我更改参数时,它不会在第一次单击时反映在组件中。 尝试将带有参数的对象放在 useEffect 中,它会永远循环

预期: 通过useEffect或执行一个函数,从前面自动更改一个参数,将新参数存储在一个钩子中再次进行查询。

(参数必须是数组,是我要复用的函数)

实际 https://codesandbox.io/s/usefetchwithrefetch-iw4r33?file=/src/App.js:739-745

App.js

import { useState } from "react";
import "./styles.css";
import useFetch from "./useFetch";

export default function App() {
  const url = "https://api.agify.io/";

  const fetcher = (urlToFetch) => {
    return fetch(urlToFetch);
  };

  const getYearByName = async (name) => {
    const response = await fetcher(url + `?name=${name}`, {
      method: "GET"
    });
    return await response.json();
  };

  const [name, setName] = useState("Nahuel");

  const { data, isLoading, getData } = useFetch([name], getYearByName);

  return (
    <div className="App">
      <button onClick={() => {
        setName("Camila") 
        getData()}}>
          Change name
      </button>
      {isLoading ? (
        <div> cargando </div>
      ) : (
        <>
          <h1>{data.name}</h1>
          <h2>{data.age}</h2>
        </>
      )}
    </div>
  );
}

useFetch.js

import { useState, useEffect } from "react";

const useFetch = (obj, functionTest) => {
  const [data, setData] = useState([]);
  const [error, setError] = useState(false);
  const [isLoading, setIsLoading] = useState(true);

  const getData = async () => {
    setIsLoading(true);
    const response = await functionTest(...obj);
    setData(response);
    setIsLoading(false);
    setError(false);
  };
  useEffect(() => {
    getData();
  }, []);

  return {
    data,
    error,
    isLoading,
    getData
  };
};

export default useFetch;

你所做的是 good.The 无限循环发生了,因为你在每次调用时都创建了一个新值 [name]!如果您想继续使用数组,请尝试破坏:

import { useState, useEffect } from "react";

const useFetch = (obj, functionTest) => {
  const [data, setData] = useState([]);
  const [error, setError] = useState(false);
  const [isLoading, setIsLoading] = useState(true);

  const getData = async () => {
    setIsLoading(true);
    const response = await functionTest(...obj);
    setData(response);
    setIsLoading(false);
    setError(false);
  };
  useEffect(() => {
    getData();
  }, [...obj]); //<--- destruct the param to prevent infinite loop

  return {
    data,
    error,
    isLoading,
    getData
  };
};

export default useFetch;

演示:https://codesandbox.io/s/usefetchwithrefetch-forked-0dcm0g