【问题标题】:Prevent checkboxes from re-rendering in React防止复选框在 React 中重新渲染
【发布时间】:2021-08-13 16:09:28
【问题描述】:

我正在尝试根据动态返回数据呈现多个复选框,并将它们的选中状态存储在本地状态中。

但是,当生成更多数量的复选框时,性能开始下降。我注意到这个问题是由于所有复选框的不断重新渲染,只要它们中的任何一个被选中(复选框状态都存储在具有不同键的同一个对象中)

这是我的示例代码和用于查看实际性能问题的代码框链接(请注意选中复选框时的延迟)

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>
  );
}

CodeSandbox

似乎每当checkboxStates 更改时,useEffect 钩子就会重新运行,再次触发所有复选框的重新渲染。

是否可以防止 React 在状态更改时再次重新渲染所有复选框?还是我们必须为每个复选框动态地创建一个单独的状态?

任何帮助将不胜感激。

【问题讨论】:

    标签: javascript reactjs checkbox react-hooks


    【解决方案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 备忘录

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-03
      • 2021-04-27
      • 2021-02-14
      • 1970-01-01
      • 1970-01-01
      • 2023-02-26
      • 2020-11-01
      • 2020-06-17
      相关资源
      最近更新 更多