嗨,我尝试渲染一个使用 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;
谢谢你
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
CustomStepper
组件是一个使用 Material-UI (MUI) 构建的多功能步进器 UI,可让您创建动态且交互式的逐步导航系统。它支持两种样式的连接器(qonto
和 colorlib
)、每个步骤的自定义图标以及用于其他操作的交互式模式。
问题:当步进器中的步骤是静态的(即不动态更改)时,组件可能会比必要的更频繁地重新渲染,这可能会影响性能。
解决方案:为了优化性能,请使用静态数组作为步骤,而不是动态生成它。这种方法可以防止不必要的重新渲染并提高效率。
为步骤定义静态数组 在组件外部定义步骤数组,以确保其保持不变并且不会触发重新渲染。
const stepsMore = ["D", "O", "E", "R", "-R"];
更新组件 使用组件内的静态数组来渲染步骤。
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
});
优化渲染 通过使用
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;