首页 > 解决方案 > Hook 不会重新渲染组件

问题描述

我将 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

标签: reactjscomponentsrenderreact-hooks

解决方案


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

React Hook useEffect 缺少依赖项:'fetchUrl'。包括它或删除依赖数组。(react-hooks/exhaustive-deps)

这里应该是这样的:

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


推荐阅读