繁体   English   中英

React Re-Render 问题:如何停止重新渲染?

[英]React Re-Render Issue : How Can I Stop Re-Render?

我是编码新手,在谷歌搜索多次后我无法解决这个问题。 问题是我有一个包含 4 个不同组件的布局组件。 当我在 function 组件中调用 function 时,它会影响其他组件并且其他组件会重新渲染。 但我不会把新道具传给他们。 我只将道具传递给一个包含点击事件的组件。 我希望我说清楚了,提前谢谢。 所以这是我的代码示例:

这是我的布局组件。

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 开箱即用的速度非常快——它应该在 props 不改变时重新渲染组件。 但是,为了说明,您可以设计您的组件(使用children ),这样就不会一直重新渲染所有内容。

比较这两个堆栈闪电战:

但这实际上并不重要,如果您发现性能问题,您应该只考虑防止不必要的渲染。

如果您看到通过阻止重新渲染来解决的逻辑问题,那么您有一个需要在其他地方修复的错误。

如果您没有遇到任何性能或逻辑问题,那么您的问题的答案就是不要担心它。

您可以使用React.memo ,但是记忆一个组件很容易最终成为性能损失,而不是胜利。 记事不是免费的。

我敦促您忘记这些东西,除非您看到性能或逻辑错误。

别担心,当你的组件重新渲染而没有道具/状态改变时,如果他们的父母已经重新渲染,一切都会正常运行

如果您在布局组件中设置新的 state,它将重新运行并重新渲染其 JSX 中的所有组件。
别担心,这不是 React 的问题。 如果您希望您的HeaderMenuCartFooter不被重新渲染,请阅读 React.PureComponent(用于类)、React.memo 或 useMemo、useCallback(用于功能组件)。

暂无
暂无

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

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