Javascript 反应重新渲染问题:如何停止重新渲染?
我是一名新的编码员,在谷歌搜索了很多次之后,我都不知道如何解决这个问题。问题是我有一个布局组件,其中包含4个不同的组件。当我在一个函数组件中调用一个函数时,它会影响其他函数,并重新渲染其他函数。但我不会把新道具传给他们。我只将道具传递给一个包含单击事件的组件。我希望我说清楚了,提前谢谢你。下面是我的代码示例: 这是我的布局组件。Javascript 反应重新渲染问题:如何停止重新渲染?,javascript,reactjs,Javascript,Reactjs,我是一名新的编码员,在谷歌搜索了很多次之后,我都不知道如何解决这个问题。问题是我有一个布局组件,其中包含4个不同的组件。当我在一个函数组件中调用一个函数时,它会影响其他函数,并重新渲染其他函数。但我不会把新道具传给他们。我只将道具传递给一个包含单击事件的组件。我希望我说清楚了,提前谢谢你。下面是我的代码示例: 这是我的布局组件。 import React, { useState } from "react"; import Header from "./Header
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;
import React,{useState}来自“React”;
从“/Header”导入标题;
从“/MenuTitle”导入MenuTitle;
从“/MenuList”导入菜单列表;
从“/Cart”导入购物车;
从“/Footer”导入页脚;
功能布局({
cartData,
美努利主义者,
Menutiles,
callMenuList,
addToCart,
标题
从购物车上取下,
货币,
}) {
const[isCartOpened,setIsCartOpened]=使用状态(“关闭”);
const openCart=()=>{
如果(isCartOpened==“closed”){
setIsCartOpened(“opened”);
}否则{
SETISCARTOPEN(“关闭”);
}
};
const closeCart=()=>{
SETISCARTOPEN(“关闭”);
};
返回(
openCart()}cartData={cartData}/>
callMenuList(titleProp)}
/>
addToCart(数据)}
/>
removeFromCart(itemId)}
isCartOpened={isCartOpened}
closeCart={()=>closeCart()}
/>
);
}
导出默认布局;
这是我的应用程序组件
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);
import React,{useState,useffect}来自“React”;
从“/Components/Layout”导入布局;
函数App(){
const[data,setData]=useState([]);
const[menutile,setmenutile]=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)=>{
设置标题(标题栏);
常量filterMenuList=data.filter((title)=>title.TYPE==titleProp);
设置菜单列表(过滤器菜单列表);
});
const addToCart=React.useCallback((数据)=>{
setCart([…购物车,数据]);
});
const removeFromCart=React.useCallback((itemId)=>{
const cartItems=购物车;
cartItems.map((项目)=>{
如果(item.CODE==itemId){
const filtered=cartItems.filter(
(cartItem)=>cartItem.CODE!=itemId
);
setCart(过滤);
}
});
});
useffect(()=>{
常量标题=[];
const fetchData=async()=>{
常量响应=等待获取(API);
const responseData=await response.json();
setData(响应数据);
控制台日志(responseData);
//筛选菜单类型
responseData.map((item)=>titles.push(item.TYPE));
const filtered=titles.filter(
(项目,索引,自我)=>self.indexOf(项目)==索引
);
setMenuTitle(已过滤);
const initialMenuList=responseData.filter(
(item)=>item.TYPE==已筛选[0]
);
setTitle(initialMenuList[0]。类型);
setCurrency(initialMenuList[0]。货币);
setMenuList(initialMenuList);
};
fetchData();
}, []);
返回(
callMenuList(titleProp)}
addToCart={(数据)=>addToCart(数据)}
removeFromCart={(itemId)=>removeFromCart(itemId)}
cartData={cart}
title={title}
货币={currency}
/>
);
}
导出默认反应备忘录(App);
如果在布局组件中设置新状态,它将重新运行并重新呈现其JSX中的所有组件。别担心,这不是反应的问题。
如果您希望您的
页眉
、菜单
、购物车
、页脚
不被重新呈现,请阅读关于React.PureComponent(对于类)、React.memo或useMemo、useCallback(对于功能组件)的内容.我必须补充这一点作为答案,尽管这更多的是一个评论,因为很多人在无关紧要的情况下过分热衷于阻止渲染
React是非常快的开箱即用-它应该是在道具不变的情况下重新渲染组件。但是,仅举个例子,您可以设计组件(使用子组件
),这样就不会一直重新渲染所有内容
比较这两个stackblitz:
React.memo
,但是记忆组件很容易会导致性能下降,而不是获胜。回忆一些东西不是免费的
我敦促您忘记这些东西,除非您看到性能或逻辑错误
别担心,当组件在没有道具的情况下重新渲染时,一切都正常运行/如果其父级已重新渲染,则状态会发生更改尝试将其他组件记忆起来。用一个
React.memo来包装它们。嘿,首先谢谢你的回答。但是这些并没有解决我的问题,我已经用它们来解决了,但对我来说不起作用。嘿,谢谢你花时间回答我的问题。但是看起来很奇怪。单击页面中的按钮时,所有组件都将重新呈现。@MithatErcan您描述的是React状态更改的标准行为。它将重新呈现组件返回的所有内容。没什么奇怪的。问题是:它会引起任何问题吗?@MithatErcan没有什么不对的。这也完全取决于你如何构造你的组件。如果使用子项
,则。