Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent checkboxes from re-rendering in React

I'm trying to render multiple checkboxes based on dynamic return data and have their checked status stored in a local state.

However the performance starts to degrade when higher number of checkboxes are generated. I noticed the issue is due to the constant re-rendering of ALL the checkboxes whenever any one of them is checked (checkbox states are all stored in the same object with different keys)

Here is my sample code and a codesandbox link to see the actual performance issue (notice the delay when a checkbox is selected)

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

It seems that whenever checkboxStates is changed, the useEffect hook is re-run, triggering a re-render of all the checkboxes again.

Is it possible to prevent React from re-rendering all the checkboxes again whenever the state is changed? Or do we have to create a separate state for every single checkbox dynamically?

Any help would be greatly appreciated.

like image 640
Alfred Avatar asked Jul 27 '26 11:07

Alfred


1 Answers

You can use React.memo to prevent re-render of unchanged check-boxes. Like this:

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

However, it might still be not fast enough as when you click the checkbox it still loops trough .map and creates elements.

Here is docs reference for Memo

like image 140
Rostyslav Avatar answered Jul 30 '26 01:07

Rostyslav



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!