简体   繁体   English

为什么 Redux state 中的 useEffect 导致无限循环:

[英]Why useEffect in Redux state is causing infinite loop:

I'm having this issue when I fetch a list of items from api. The axios make a get request in the action.当我从 api 获取项目列表时遇到此问题。axios 在操作中发出获取请求。 send to reducer and makes change in the state. So I want the list to update only when the user adds, removes or update a item.发送到 reducer 并在 state 中进行更改。所以我希望列表仅在用户添加、删除或更新项目时更新。 I'm using the useEffect hook passing the list as dependency to change, but it's just fetching in infinite loop, affecting the performance tremendously.我正在使用 useEffect 挂钩将列表作为依赖项传递给更改,但它只是在无限循环中获取,极大地影响了性能。

Action creator:动作创造者:

import axios from "axios";
const BASE_URL = "https://localhost:5001/api";

export function getList() {
  return (dispacth) => {
    return axios.get(`${BASE_URL}/billingCycles`).then((res) =>
      dispacth({
        type: "BILLING_CYCLES_FETCHED",
        payload: res.data,
      })
    );
  };
}

Reducer:减速器:

const INITIAL_STATE = { list: [], billingCycle: {}, credits: [], debts: [] };

// eslint-disable-next-line import/no-anonymous-default-export
export default function (state = INITIAL_STATE, action) {
  switch (action.type) {
    case "BILLING_CYCLES_FETCHED":
      return { ...state, list: action.payload };
  ..MORE CASES BELOW...
  }
}

List component:列表组件:

import React, { useEffect } from "react";

import ListItem from "./ListItem";

import { getList } from "../../store/actions/billingCycleActions";
import { setCreate } from "../../store/actions/modalActions";
import { useDispatch, useSelector } from "react-redux";

function List() {
  const dispatch = useDispatch();
  const billingCycles = useSelector((state) => state.billingCycles.list);

  // eslint-disable-next-line react-hooks/exhaustive-deps
  useEffect(() => dispatch(getList()), [billingCycles]);

  return (
    <div>
      <div className="mb-3 d-flex justify-content-lg-start">
        <button
          className="btn btn-success"
          onClick={() => dispatch(setCreate(true))}
        >
          <i className="fas fa-plus m-1"></i>
          Novo ciclo!
        </button>
      </div>
      <table className="table table-hover border ">
        <thead className="border">
          <tr>
            <th>Nome</th>
            <th>Mês</th>
            <th>Ano</th>
            <th>Ações</th>
          </tr>
        </thead>
        <tbody>
          {billingCycles &&
            billingCycles
              .map((el) => {
                return (
                  <ListItem
                    index={el.id}
                    name={el.name}
                    month={el.month}
                    year={el.year}
                  />
                );
              })
              .reverse()}
        </tbody>
      </table>
    </div>
  );
}

export default List;

Here's a image of the Redux debug tool:这是 Redux 调试工具的图像: 在此处输入图像描述

If you need to get the list only in the initial render, leave the dependency array empty, so it will only invoke once如果只需要在初始渲染中获取列表,请将依赖项数组留空,这样它只会调用一次

useEffect(() => dispatch(getList()), []);

Otherwise, your fetch will mutate the billingCycles causing re-render over again which ended up with an infinite loop.否则,您的提取将改变billingCycles ,导致重新渲染,最终导致无限循环。


More on that here更多关于这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM