为什么 Redux 状态下的 useEffect 会导致无限循环:
Why useEffect in Redux state is causing infinite loop:
我在从 api 获取项目列表时遇到了这个问题。 axios 在操作中发出 get 请求。发送到减速器并改变状态。所以我希望列表仅在用户添加、删除或更新项目时更新。我正在使用 useEffect 挂钩将列表作为依赖项传递给更改,但它只是在无限循环中获取,极大地影响了性能。
动作创作者:
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,
})
);
};
}
减速器:
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...
}
}
列表组件:
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;
这是 Redux 调试工具的图片:
如果您只需要在初始渲染时获取列表,请将依赖项数组留空,这样它只会调用一次
useEffect(() => dispatch(getList()), []);
否则,您的提取将改变 billingCycles
,导致 re-render 再次发生,最终导致无限循环。
更多相关信息here
我在从 api 获取项目列表时遇到了这个问题。 axios 在操作中发出 get 请求。发送到减速器并改变状态。所以我希望列表仅在用户添加、删除或更新项目时更新。我正在使用 useEffect 挂钩将列表作为依赖项传递给更改,但它只是在无限循环中获取,极大地影响了性能。
动作创作者:
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,
})
);
};
}
减速器:
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...
}
}
列表组件:
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;
这是 Redux 调试工具的图片:
如果您只需要在初始渲染时获取列表,请将依赖项数组留空,这样它只会调用一次
useEffect(() => dispatch(getList()), []);
否则,您的提取将改变 billingCycles
,导致 re-render 再次发生,最终导致无限循环。
更多相关信息here