reactjs 当一个属性改变时,如何运行一个自定义钩子?

carvr3hs  于 2022-12-03  发布在  React
关注(0)|答案(2)|浏览(132)

我创建了一个自定义钩子,它接受一个url并返回数据

import { useEffect, useState } from "react";

export function useHttp({ url }: { url: string }) {
  const [data, setData] = useState<any>(null);

 useEffect(() => {
    const controller = new AbortController();
    const signal = controller.signal;
    fetch(url, { signal })
      .then((res) => res.json())
      .then((data) => setData(data))
      .catch((err) => {
        if (err.name === "AbortError") {
          console.log("successfully aborted");
        } else {
          // handle error
        }
      });

    return () => {
      // cancel the request before component unmounts
      controller.abort();
    };
  }, []);

  return data ;
}

我正在使用钩子来获取我的主页中的数据,这工作正常

import { useState } from "react";
import { useHttp } from "./useHttp";
import "./App.css";

type person = { name: string; id: number };
function App() {
  const [selectedId, setSelectedId] = useState<number>(1);
  const people = useHttp({ url: "https://jsonplaceholder.typicode.com/users" });

  return (
    <div className="App">
      {(people as unknown as person[])?.map(({ id, name }) => (
        <button key={id} onClick={() => setSelectedId(id)}>
          {name}
        </button>
      ))}
      <br />
      <InnerComponent selectedId={selectedId} />
    </div>
  );
}

我遇到的问题是,我试图在子组件中再次重用钩子,以获取有关依赖于主组件中某个值的详细信息

const InnerComponent = ({ selectedId }: { selectedId: number }) => {
  console.log(selectedId)
  const person = useHttp({
    url: `https://jsonplaceholder.typicode.com/users/${selectedId}`,
  });

  return <div>{person?.name}</div>;
};

我还可以看到prop值已经更改,我的hook没有重新运行,如何在不重写useEffect中的逻辑的情况下实现它?
我希望钩子在属性改变时重新运行并获取结果,但它在初始渲染中只运行一次

2w2cym1i

2w2cym1i1#

就像另一个答案所说的,你的钩子依赖于url参数,所以它应该被包含在useEffect调用的依赖数组中。

useEffect(() => {
    // ...
  }, [url]);

另外,你应该花一些时间学习如何在你的项目中配置eslint。大多数模板中的默认eslint配置会强制你在依赖项数组中包含所有依赖项。这样你就不必每次都手动地做这件事。

rjee0c15

rjee0c152#

使用相依性数组

export function useHttp({ url }: { url: string }) {
  const [data, setData] = useState<any>(null);

  useEffect(() => {
    // ...
  }, [url]);

  return data ;
}

相关问题