如何让 useEffect 不无限重新渲染
How to get useEffect to not re-render infinitely
我在使用 Redux-thunk 进行 AJAX 调用后尝试渲染这个 CardsContainerCopy 组件。
如果我将 useEffect 中的 dependencies 数组留空,则组件根本不会呈现。
如果我将 cartItems
添加到 dependencies 数组,组件将呈现,但 fetchItems
函数会一直被无限调用。
代码:
import React, { useEffect, useState } from "react";
import SingleCard from "./SingleCard";
import { createServer } from "miragejs";
import axios from "axios";
import itemsData from "../../config/ItemsData";
import { useDispatch, useSelector } from "react-redux";
import { selectCartItems } from "./shopSlice";
let server = createServer();
server.get("/api/food", itemsData);
const fetchItems = async (dispatch) => {
const itemsData = await axios.get("/api/food");
dispatch({ type: "shop/fetchedItems", payload: itemsData.data });
};
const CardsContainerCopy = () => {
const [items, setItems] = useState([]);
const dispatch = useDispatch();
const cartItems = useSelector(selectCartItems);
useEffect(() => {
dispatch(fetchItems);
setItems(cartItems);
}, [cartItems]);
return (
<>
{items?.map((item, i) => {
return <SingleCard props={item} key={i} />;
})}
</>
);
};
export default CardsContainerCopy;
您的 useEffect 函数确实创建了一个无限循环,因为您正在收听 cartItems 更改,这会再次触发调度。为了避免无限重新渲染,你可以这样做:
const CardsContainerCopy = () => {
const [items, setItems] = useState([]);
const dispatch = useDispatch();
const cartItems = useSelector(selectCartItems);
useEffect(()=>{
dispatch(fetchItems);
}, [])
useEffect(() => {
setItems(cartItems);
}, [cartItems]);
return (
<>
{items?.map((item, i) => {
return <SingleCard props={item} key={i} />;
})}
</>
);
};
我在使用 Redux-thunk 进行 AJAX 调用后尝试渲染这个 CardsContainerCopy 组件。
如果我将 useEffect 中的 dependencies 数组留空,则组件根本不会呈现。
如果我将 cartItems
添加到 dependencies 数组,组件将呈现,但 fetchItems
函数会一直被无限调用。
代码:
import React, { useEffect, useState } from "react";
import SingleCard from "./SingleCard";
import { createServer } from "miragejs";
import axios from "axios";
import itemsData from "../../config/ItemsData";
import { useDispatch, useSelector } from "react-redux";
import { selectCartItems } from "./shopSlice";
let server = createServer();
server.get("/api/food", itemsData);
const fetchItems = async (dispatch) => {
const itemsData = await axios.get("/api/food");
dispatch({ type: "shop/fetchedItems", payload: itemsData.data });
};
const CardsContainerCopy = () => {
const [items, setItems] = useState([]);
const dispatch = useDispatch();
const cartItems = useSelector(selectCartItems);
useEffect(() => {
dispatch(fetchItems);
setItems(cartItems);
}, [cartItems]);
return (
<>
{items?.map((item, i) => {
return <SingleCard props={item} key={i} />;
})}
</>
);
};
export default CardsContainerCopy;
您的 useEffect 函数确实创建了一个无限循环,因为您正在收听 cartItems 更改,这会再次触发调度。为了避免无限重新渲染,你可以这样做:
const CardsContainerCopy = () => {
const [items, setItems] = useState([]);
const dispatch = useDispatch();
const cartItems = useSelector(selectCartItems);
useEffect(()=>{
dispatch(fetchItems);
}, [])
useEffect(() => {
setItems(cartItems);
}, [cartItems]);
return (
<>
{items?.map((item, i) => {
return <SingleCard props={item} key={i} />;
})}
</>
);
};