挂钩不会释放组件

时间:2019-05-18 09:32:45

标签: reactjs components render react-hooks

我正在将React与React-Router-Dom一起使用,我不知道为什么当URL更改时我的子组件(功能组件)不重新呈现。而且我不知道为什么,当我第一次访问动态页面时,console.log(url)被触发了3次?

我的孩子部分:

import React from "react";
import { useFetch } from "./hooks";

function Page(props) {
  const url = "https://jsonplaceholder.typicode.com/posts" + props.match.url;
  console.log(url);

  const [data, loading] = useFetch(url);

  return (
    <>
      {loading ? (
        "Loading..."
      ) : (
        <>
          <h1>{data.title}</h1>
          <p>{data.body}</p>
        </>
      )}
    </>
  );
}
export default Page;

可以使用沙箱获取更完整的示例:https://codesandbox.io/embed/great-mahavira-5ktrk

1 个答案:

答案 0 :(得分:1)

您的子组件重新渲染,但是它使用了先前渲染中的旧数据。发生这种情况是因为您没有将url作为依赖项传递给useEffect挂钩。并且最好将fetchUrl函数移到useEffect内(如果您不想在其他地方使用它),因为现在eslint会出现错误:

  

反应挂钩useEffect缺少依赖项:'fetchUrl'。包括它或删除依赖项数组。 (反应钩/详尽的下降)

它的外观如下:

function useFetch(url) {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function fetchUrl() {
      const response = await fetch(url);
      const json = await response.json();
      setData(json);
      setLoading(false);
    }

    fetchUrl();
  }, [url]);
  return [data, loading];
}

“而且我不知道为什么,当我第一次访问动态页面时,console.log(url)触发了3次?”

发生这种情况是因为您的组件重新渲染3次:

  1. 安装时。

  2. 当挂机呼叫setData(json)时。

  3. 当挂机呼叫setLoading(false)时。

这里的工作示例:https://codesandbox.io/embed/condescending-wildflower-v8m4c