useEffect 被多次调用

问题描述 投票:0回答:2

我正在使用 Express API 从 MySQL 数据库获取系列列表。我检查了 Express 日志,发现该请求已发出 2 次。我通过控制台记录了 React 组件和 useEffect 挂钩,并看到组件本身渲染了 5-6 次,useEffect 渲染了 2 次(基于 chrome 浏览器中的控制台日志输出)。我究竟做错了什么?这是我的代码:

import React, { useState, useEffect } from 'react';
import { useDispatch, useSelector } from "react-redux";
import { fetchSeries } from '../../Redux/Actions/SeriesActions';

const MyList = () => {
  const [isSeriesOpen, setIsSeriesOpen] = useState(false);
  const dispatch = useDispatch();
  const series = useSelector((state) => state.seriesList.series);
  const userId = useSelector((state) => state.auth.user_id);
  const companyId = 3;

  console.log("Log from the component");

  useEffect(() => {
    dispatch(fetchSeries(userId, companyId));
    console.log("Log for Effect called");
  }, [dispatch]);


  return (
    <div>
      <p> Test Content</p>
    </div>
  );
};

export default MyList;

我尝试检查是否有任何东西使组件重新渲染。该组件被导入到 Routes 中,而 Routes 被导入到 App.js 中,而 App.js 又被导入到 index.js 中。但这是 React 的正常结构,不是吗?我不明白为什么 useEffect 被调用了 2 次,因此向 api 发出了 2 个请求,导致它在数据库上运行查询 2 次。

reactjs express react-hooks react-redux
2个回答
0
投票

React 在开发过程中渲染两次。

参见:

”严格模式无法自动为你检测副作用,但是 它可以通过使它们更具确定性来帮助您发现它们。 这是通过有意两次调用以下函数来完成的: 类组件构造函数、渲染和shouldComponentUpdate 方法。”

来源:React 文档:严格模式

此外,您应该将 useEffect 中使用的所有变量添加到末尾的依赖项数组中

  useEffect(() => {
    dispatch(fetchSeries(userId, companyId));
    console.log("Log for Effect called");
  }, [dispatch, userId, companyId]);

0
投票

目前,你有[dispatch]作为依赖数组,这意味着每当dispatch发生变化时,效果就会重新执行。由于dispatch是Redux提供的函数,每次渲染时都会发生变化,导致效果被执行多次。

要解决此问题,您应该将影响依赖项数组内效果的所有依赖项包含在内。在您的情况下, userId 和 companyId 可能是依赖项,当它们发生更改时,应该触发效果重新运行。以下是修改 useEffect 挂钩的方法:

useEffect(() => {
  dispatch(fetchSeries(userId, companyId));
  console.log("Log for Effect called");
}, [dispatch, userId, companyId]);
© www.soinside.com 2019 - 2024. All rights reserved.