使用 MUI 和样式组件进行太多重新渲染

问题描述 投票:0回答:2

嗨,我尝试渲染一个使用 MUI(Material-UI)和样式组件的页面。我已经使用主题和使用媒体查询来使我的网络应用程序响应。我尝试使我的应用程序响应并更改字体大小(如果它是小型设备)

我遇到的问题是根据控制台渲染太多

我知道问题出在 useState 的 if else 语句上,但我不知道还有什么其他选择可以实现这一点

以下代码:

import React, { useState } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Button from '@material-ui/core/Button';
import { Link } from 'react-router-dom';
import Logojsam from '../../assets/icons/logo-jsam.png';

import useMediaQuery from '@material-ui/core/useMediaQuery';
import { useTheme } from '@material-ui/core/styles';

import styled from 'styled-components';
const useStyles = makeStyles((theme) => ({
  rightToolbar: {
    marginLeft: 'auto',
    marginRight: -10,
  },
  logo: {
    width: 185,
    height: 185,
    padding: '20px 0px',
  },
}));

const MyButton = styled(Button)({
  padding: '0 14px',
  fontSize: (props) => props.fontSize || '20px',
});



const Navbar = () => {
  const classes = useStyles();
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
  const isMedium = useMediaQuery(theme.breakpoints.down('md'));

  const [fontSize, setfontSize] = useState();
 
  if (isMedium)
  {
    setfontSize('45px');
  }
    return (
      <div>
        <AppBar
          position="static"
          elevation={0}
          style={{
            background: 'white',
          }}
        >
          <Toolbar>
            <img className={classes.logo} src={Logojsam} alt="Bosch Logo" />
            {!isMobile && (
              <section className={classes.rightToolbar}>
                <MyButton fontSize={fontSize} component={Link} to="/">
                  About Us
                </MyButton>
                <MyButton component={Link} to="/community">
                  Community
                </MyButton>
                <MyButton component={Link} to="/community">
                  Activities
                </MyButton>
                <MyButton component={Link} to="/gallery">
                  Gallery
                </MyButton>
                <MyButton component={Link} to="/contact-us">
                  Contact Us
                </MyButton>
                <MyButton component={Link} to="/contact-us">
                  En
                </MyButton>
              </section>
            )}
          </Toolbar>
        </AppBar>
      </div>
    );
};

export default Navbar;



谢谢你

javascript reactjs react-hooks material-ui styled-components
2个回答
0
投票

useEffect()
Hook 允许您在函数组件中执行副作用。正如评论中所述。通过 Jayce444,当您在组件主体内调用
setfontSize()
时,它会触发重新渲染。将其放入 useEffect 中,并且仅在
isMedium
发生变化时重新运行

import React, { useState, useEffect } from 'react';

然后

useEffect(() => {
  if (isMedium){
    setfontSize('45px')
  }
}, [isMedium]); // Only re-run the effect if isMedium changes

0
投票

自定义Stepper组件

概述

CustomStepper
组件是一个使用 Material-UI (MUI) 构建的多功能步进器 UI,可让您创建动态且交互式的逐步导航系统。它支持两种样式的连接器(
qonto
colorlib
)、每个步骤的自定义图标以及用于其他操作的交互式模式。

特点

  • 可自定义样式:在不同的连接器样式之间进行选择,并使用不同的颜色自定义每个步骤的外观。
  • 交互式步骤:单击步骤可打开用于其他操作或信息的模式。
  • 工具提示:将鼠标悬停在步骤上可查看包含描述性信息的工具提示。

静态数组问题及解决方案

问题:当步进器中的步骤是静态的(即不动态更改)时,组件可能会比必要的更频繁地重新渲染,这可能会影响性能。

解决方案:为了优化性能,请使用静态数组作为步骤,而不是动态生成它。这种方法可以防止不必要的重新渲染并提高效率。

实施步骤

  1. 为步骤定义静态数组 在组件外部定义步骤数组,以确保其保持不变并且不会触发重新渲染。

    const stepsMore = ["D", "O", "E", "R", "-R"];
    
  2. 更新组件 使用组件内的静态数组来渲染步骤。

    const CustomStepper = React.memo(function CustomStepper({
      steps,
      activeStep,
      connectorType = "qonto",
      icons,
      highlightStep,
      label_status,
      HandleAddRating,
      stepColors,
    }) {
      // Static steps array
      const stepsMore = ["D", "O", "E", "R", "-R"];
    
      // ... Rest of the component code
    });
    
  3. 优化渲染 通过使用

    Stepper
    并优化道具比较,确保
    React.memo
    组件仅在必要时重新渲染。

完整组件代码

import React, { useCallback, useMemo, useState } from "react";
import { styled } from "@mui/material/styles";
import Stack from "@mui/material/Stack";
import Stepper from "@mui/material/Stepper";
import Step from "@mui/material/Step";
import StepLabel from "@mui/material/StepLabel";
import Check from "@mui/icons-material/Check";
import StepConnector, { stepConnectorClasses } from "@mui/material/StepConnector";
import DropdownModal from "../DropdownModal/DropdownModal";
import Tooltip from "@mui/material/Tooltip";

// Styles for connectors and step icons
// (Styles as provided above)

// Component definition
const CustomStepper = React.memo(function CustomStepper({
  steps,
  activeStep,
  connectorType = "qonto",
  icons,
  highlightStep,
  label_status,
  HandleAddRating,
  stepColors,
}) {
  const Connector = useMemo(
    () => (connectorType === "colorlib" ? ColorlibConnector : QontoConnector),
    [connectorType]
  );

  const StepIconComponent = useMemo(
    () => (connectorType === "colorlib" ? ColorlibStepIcon : QontoStepIcon),
    [connectorType]
  );

  const [modalOpen, setModalOpen] = useState(false);
  const [selectedIcon, setSelectedIcon] = useState("D");

  const handleStepClick = useCallback(
    (icon, index) => {
      setSelectedIcon(icon);
      if (stepColors[index] !== "#4caf50") {
        setModalOpen(true);
      }
    },
    [stepColors]
  );

  const handleClose = useCallback(() => setModalOpen(false), []);

  const allStepsCompleted = useMemo(
    () => activeStep >= steps.length,
    [activeStep, steps.length]
  );

  const handleSaveRating = useCallback(
    (ratingObject) => {
      HandleAddRating(ratingObject);
      setModalOpen(false);
    },
    [HandleAddRating]
  );

  const stepsMore = ["D", "O", "E", "R", "-R"];

  return (
    <>
      {connectorType === "colorlib" ? (
        <ColorlibGlobalStyles />
      ) : (
        <GlobalStyles />
      )}
      <Stack sx={{ width: "100%" }} spacing={4}>
        <Stepper
          alternativeLabel
          activeStep={activeStep}
          connector={<Connector stepColor={stepColors[activeStep]} />}
        >
          {stepsMore.map((label, index) => (
            <Step key={label}>
              <Tooltip title={steps[index]} arrow>
                <span>
                  <StepLabel
                    StepIconComponent={(props) => (
                      <StepIconComponent
                        {...props}
                        icon={icons ? icons[index + 1] : undefined}
                        onClick={() =>
                          handleStepClick(icons[index + 1], index)
                        }
                        highlight={highlightStep === index}
                        stepColor={stepColors[index]}
                        allCompleted={allStepsCompleted}
                      />
                    )}
                  >
                    <span>{label}</span>
                  </StepLabel>
                </span>
              </Tooltip>
            </Step>
          ))}
        </Stepper>
      </Stack>
      <DropdownModal
        open={modalOpen}
        handleClose={handleClose}
        selectedIcon={selectedIcon}
        HandleAddRating={handleSaveRating}
        step_name={steps[activeStep]}
        label_status={label_status}
      />
    </>
  );
}, (prevProps, nextProps) => {
  return (
    prevProps.activeStep === nextProps.activeStep &&
    prevProps.connectorType === nextProps.connectorType &&
    prevProps.highlightStep === nextProps.highlightStep &&
    prevProps.label_status === nextProps.label_status &&
    JSON.stringify(prevProps.steps) === JSON.stringify(nextProps.steps) &&
    JSON.stringify(prevProps.stepColors) ===
      JSON.stringify(nextProps.stepColors)
  );
});

export default CustomStepper;
© www.soinside.com 2019 - 2024. All rights reserved.