我正在尝试基于动态返回数据呈现多个复选框,并将其选中状态存储在本地状态。
但是,当生成更多复选框时,性能开始下降。我注意到这个问题是由于恒定ALL每当它们中的任何一个被选中的复选框的重新呈现(复选框的状态都存储在用不同的密钥相同的对象)
这是我的示例代码和一个codeandbox链接,用于查看实际的性能问题(请注意选中复选框时的延迟)
export default function App() {
const [checkboxResponse, setCheckboxResponse] = useState([]);
const [checkboxList, setCheckboxList] = useState();
const [checkboxStates, setCheckboxStates] = useState({});
useEffect(() => {
//Generate dummy data
const dummyData = [];
for (let i = 0; i < 1000; i++) {
dummyData.push(i.toString());
}
//Set dummyData as checkbox dynamic data
setCheckboxResponse(dummyData);
}, []);
useEffect(() => {
//When checkbox is clicked, add to local checkbox states object
const checkboxChange = key => event => {
setCheckboxStates({ ...checkboxStates, [key]: event.target.checked });
};
//Check if data is available
if (checkboxResponse) {
const checkboxes = checkboxResponse.map(key => {
const value = checkboxStates[key] ? checkboxStates[key] : false;
//Render checkbox
return (
<FormControlLabel
key={key}
checked={value}
control={
<Checkbox
size="small"
value={key}
onChange={checkboxChange(key)}
/>
}
label={key}
/>
);
});
setCheckboxList(checkboxes);
}
}, [checkboxResponse, checkboxStates]);
return (
<div className="App">
{checkboxList}
</div>
);
}
似乎只要更改checkboxStates
,useEffect
钩子都会重新运行,从而再次触发所有复选框的重新渲染。
是否可以防止每当状态更改时React再次重新渲染所有复选框?还是我们必须为每个复选框动态创建一个单独的状态?
任何帮助将不胜感激。
答案 0 :(得分:1)
您可以使用React.memo
来防止重新呈现未更改的复选框。像这样:
import React, { useState, useEffect } from "react";
import { Checkbox, FormControlLabel } from "@material-ui/core";
import "./styles.css";
export default function App() {
const [checkboxResponse, setCheckboxResponse] = useState([]);
const [checkboxStates, setCheckboxStates] = useState({});
//When checkbox is clicked, add to local checkbox states object
const checkboxChange = key => event => {
setCheckboxStates({ ...checkboxStates, [key]: event.target.checked });
};
useEffect(() => {
//Generate dummy data
const dummyData = [];
for (let i = 0; i < 1000; i++) {
dummyData.push(i.toString());
}
//Set dummyData as checkbox dynamic data
setCheckboxResponse(dummyData);
}, []);
return (
<div className="App">
{checkboxResponse.map(key => {
const value = checkboxStates[key] ? checkboxStates[key] : false;
//Render checkbox
return (
<FormControlLabel
key={key}
checked={value}
control={<MemoCheckbox key={key} checkboxChange={checkboxChange} />}
label={key}
/>
);
})}
</div>
);
}
const CustomCheckbox = ({ key, checkboxChange }) => (
<Checkbox size="small" value={key} onChange={checkboxChange(key)} />
);
const MemoCheckbox = React.memo(
CustomCheckbox,
(prev, next) => prev.key === next.key
);
但是,它可能仍然不够快,因为当您单击复选框时,它仍会循环通过.map
并创建元素。
这里是备忘录的docs reference