javascript - 防止复选框在 React 中重新渲染
问题描述
我正在尝试根据动态返回数据呈现多个复选框,并将它们的检查状态存储在本地状态中。
但是,当生成更多数量的复选框时,性能开始下降。我注意到这个问题是由于所有复选框的不断重新渲染,只要它们中的任何一个被选中(复选框状态都存储在具有不同键的同一个对象中)
这是我的示例代码和用于查看实际性能问题的代码框链接(请注意选中复选框时的延迟)
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 再次重新渲染所有复选框?还是我们必须动态地为每个复选框创建一个单独的状态?
任何帮助将不胜感激。
解决方案
您可以使用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
并创建元素。
这是备忘录的文档参考
推荐阅读
- javascript - Reactjs Link 在 IE11 上不起作用,但在 Edge 和其他浏览器上起作用
- java - 动态bean创建spring
- laravel - Laravel 项目图片在实时网站上上传错误,但在 localhost 上成功运行
- amazon-web-services - 需要在同一路径nginx上运行api
- c# - MVC DropDownListFor空引用
- python-3.x - 从列表中删除字典而不提及键的有效方法
- java - 使用 Apache Async HTTP 客户端从 InputStream 构造多部分请求
- c# - 列表中的快速序列检查
- python - 使用多个 GPU 运行 LSTM 会得到“输入和隐藏张量不在同一设备上”
- mysql - 要设置什么数据类型?