React重新渲染问题:我如何停止重新渲染?



我是新的编码,我无法得到如何解决这个问题后,我谷歌了很多次。问题是我有一个布局组件,其中包含4个不同的组件。当我在一个函数组件中调用一个函数时,它会影响其他组件,而其他组件会重新渲染。但我不会把新道具传给他们。我只把道具传递给一个包含点击事件的组件。我希望我说得很清楚,提前谢谢。下面是我的代码示例:

这是我的布局组件。

import React, { useState } from "react";
import Header from "./Header";
import MenuTitle from "./MenuTitle";
import MenuList from "./MenuList";
import Cart from "./Cart";
import Footer from "./Footer";
function Layout({
cartData,
menuList,
menuTitles,
callMenuList,
addToCart,
title,
removeFromCart,
currency,
}) {
const [isCartOpened, setIsCartOpened] = useState("closed");
const openCart = () => {
if (isCartOpened == "closed") {
setIsCartOpened("opened");
} else {
setIsCartOpened("closed");
}
};
const closeCart = () => {
setIsCartOpened("closed");
};
return (
<div>
<Header openCart={() => openCart()} cartData={cartData} />
<MenuTitle
menuTitles={menuTitles}
callMenuList={(titleProp) => callMenuList(titleProp)}
/>
<MenuList
title={title}
menuList={menuList}
addToCart={(data) => addToCart(data)}
/>
<Cart
currency={currency}
cartData={cartData}
removeFromCart={(itemId) => removeFromCart(itemId)}
isCartOpened={isCartOpened}
closeCart={() => closeCart()}
/>
<Footer />
</div>
);
}
export default Layout;

这是我的App组件

import React, { useState, useEffect } from "react";
import Layout from "./Components/Layout";
function App() {
const [data, setData] = useState([]);
const [menuTitle, setMenuTitle] = useState([]);
const [title, setTitle] = useState("");
const [currency, setCurrency] = useState("");
const [menuList, setMenuList] = useState([]);
const [cart, setCart] = useState([]);
const API = "./db.json";
const callMenuList = React.useCallback((titleProp) => {
setTitle(titleProp);
const filterMenuList = data.filter((title) => title.TYPE == titleProp);
setMenuList(filterMenuList);
});
const addToCart = React.useCallback((data) => {

setCart([...cart, data]);
});
const removeFromCart = React.useCallback((itemId) => {
const cartItems = cart;
cartItems.map((item) => {
if (item.CODE == itemId) {
const filtered = cartItems.filter(
(cartItem) => cartItem.CODE != itemId
);
setCart(filtered);
}
});
});
useEffect(() => {
const titles = [];
const fetchData = async () => {
const response = await fetch(API);
const responseData = await response.json();
setData(responseData);
console.log(responseData);
// Filtering menu types
responseData.map((item) => titles.push(item.TYPE));
const filtered = titles.filter(
(item, index, self) => self.indexOf(item) == index
);
setMenuTitle(filtered);
const initialMenuList = responseData.filter(
(item) => item.TYPE == filtered[0]
);
setTitle(initialMenuList[0].TYPE);
setCurrency(initialMenuList[0].CURRENCY);
setMenuList(initialMenuList);
};
fetchData();
}, []);
return (
<Layout
menuTitles={menuTitle}
menuList={menuList}
data={data}
callMenuList={(titleProp) => callMenuList(titleProp)}
addToCart={(data) => addToCart(data)}
removeFromCart={(itemId) => removeFromCart(itemId)}
cartData={cart}
title={title}
currency={currency}
/>
);
}
export default React.memo(App);

我不得不把这个作为一个答案,尽管它更像是一个评论,因为很多人在无关紧要的时候变得过于热衷于阻止渲染。

React是非常快的开箱即用-它应该是重新渲染组件时,道具没有改变。但是,只是为了说明,您可以设计您的组件(使用children),以便不是所有内容都一直重新渲染。

比较这两个stackblitz

  • withchildren- C2 doesNOTrerender
  • 不含children- C2不渲染

但是这些实际上都不重要,您应该只在看到性能问题时考虑防止不必要的渲染。

如果你看到逻辑问题通过防止重新渲染来修复,那么你就有一个bug,你需要在其他地方修复。

如果你没有遇到任何性能或逻辑问题,那么你的问题的答案是停止担心它。

您可以使用React.memo,但是记忆组件很容易导致性能损失,而不是优势。背诵东西不是免费的。

我建议你忘记这些东西,除非你看到性能或逻辑错误。

不要担心,当你的组件重新渲染时,没有道具/状态改变,如果他们的父母重新渲染

如果您在布局组件中设置了一个新状态,它将重新运行并重新呈现其JSX中的所有组件。别担心,这不是React的问题。如果你想要你的Header,Menu,Cart,Footer不被重新渲染,阅读React。PureComponent(用于类),React。memo,或者useMemo, useCallback(对于功能组件)

最新更新