首页 > 解决方案 > 我的 Reactjs 程序不断执行 useEffect 挂钩,而我希望它只执行一次

问题描述

import React, { useEffect } from "react";
import useHttp from "./hooks/use-http";

export default function App() {
  const getReq = async () => {
    const response = await fetch(
      "" // assume this to be a random link fetching data
    );
    const responseData = await response.json();
    return responseData;
  };

  const { sendRequest, data } = useHttp(getReq);

  useEffect(() => {
    sendRequest();
  }, []);

  console.log(data);

  return <div></div>;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

import React, { useState } from "react";

const useHttp = (getReq) => {
  const [data, setData] = useState([]);
  const sendRequest = async () => {
    try {
      const data = await getReq();
      setData(data);
    } catch (error) {}
  };

  return {
    sendRequest,
    data,
  };
};

export default useHttp;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

在 useEffect 钩子中,如果我将 sendRequest 作为依赖项删除(如本例中所做的那样),我不会遇到任何问题,并且该钩子只运行一次。

但是,如果我将它添加为依赖项(出于良好实践目的),则挂钩会连续运行,并且我会得到重复出现的 console.log 语句。有人可以解释为什么会这样吗?

标签: reactjsreact-hooks

解决方案


但是,如果我将它添加为依赖项(出于良好实践目的),则挂钩会连续运行,并且我会得到重复出现的 console.log 语句。有人可以解释为什么会这样吗?

因为sendRequest是一个函数,每次重新渲染组件时都会重新创建,因此,每次渲染都不同。因此,当它被列为依赖项时,会useEffect重新运行。考虑使用useCallback和包装sendRequest使用它。


考虑重新渲染与被重新调用的函数相同的组件,因此您正在从头开始创建其中的所有变量或函数(React 小心在重新渲染时保留变量值的情况除外;这发生在例如来自状态的变量)。


推荐阅读