Skip to content Skip to sidebar Skip to footer

How To Avoid Rerender All Child Components Which In Loop When Parent Component State Update

I m having one child component which is inside a loop of parent component. when one of the child components is updating the state of parent component, it is re-rendering the all ch

Solution 1:

for that you can use React.memo that will memoize your component if props remains the same. But given your code you need to make some extra changes:

  • you have to apply useCallback to memoize onChangeHandle function;

  • to memoize properly onChangeHandle you need to refactor it. you can't pass selectedChild directly, otherwise it memoizes its value. use setSelectedChild passing as argument a function that takes selectedChild instead.

  • your Child should receive isSelected as boolean value instead of function. otherwise props will remain the same and Child never updates;

    import React, { useState, memo, useCallback } from "react";
    
    function Parent() {
      const [selectedChild, setSelectedChild] = useState([]);
    
      const onChangeHandle = useCallback((event, id) => {
        setSelectedChild(selectedChild => {
          const checked = event.target.checked;
          let updatedArray = [...selectedChild];
          if (checked) {
            if (!selectedChild.includes(id)) {
              updatedArray.push(id);
            }
          } else {
            var index = updatedArray.indexOf(id);
            if (index !== -1) {
              updatedArray.splice(index, 1);
            }
          }
          return updatedArray;
        });
      }, []);
    
      const dummy = id => {
        return selectedChild.includes(id);
      };
    
      const renderChildren = () =>
        [1, 2, 3].map((value, index) => {
          return (
            <Child
              key={index}
              index={index}
              value={value}
              handle={onChangeHandle}
              isSelected={dummy(index)}
            />
          );
        });
    
      return (
        <div>
          <table>
            <tbody>{renderChildren()}</tbody>
          </table>
          <div>{selectedChild}</div>
        </div>
      );
    }
    
    const Child = memo(({ index, value, handle, isSelected }) => {
      console.log("rendering");
    
      return (
        <tr>
          <td>
            <input
              type="checkbox"
              checked={isSelected}
              onChange={event => handle(event, index)}
            />
          </td>
          <td>
            hello {index} {value}
          </td>
        </tr>
      );
    });
    
    export default function App() {
      return (
        <div className="App">
          <Parent />
        </div>
      );
    }
    

https://stackblitz.com/edit/so-memo-children?file=src/App.js


Solution 2:

The basic answer is use React.memo on Child.

const Child = memo(function Child(...) {...})

But to make memo work, the component needs to receive the same props if it shouldn't get rerendered. That means using useCallback on onChangeHandle:

 const onChangeHandle = useCallback((event, id) => {...}, [])

But since onChangeHandle uses selectedChild that always changes on checkbox change, you'll also need to ref it using useRef:

const selectedChildRef = useRef();
selectedChildRef.current = selectedChild;

and use reffed version inside of onChangeHandle.

The last thing that needs to be done is to change isSelected prop from function to just a flag since it needs to be run on each checkbox change:

isSelected={selectedChild.includes(index)}

https://codesandbox.io/s/newpro-forked-wxvqs


Solution 3:

You could implement shouldComponentUpdate (doc: https://reactjs.org/docs/react-component.html#shouldcomponentupdate) inside the definition of Child to have more control over when it rerenders. But that's only meant for cases where you have performance issues- generally you don't have to worry about it, and letting them all rerender is standard.


Post a Comment for "How To Avoid Rerender All Child Components Which In Loop When Parent Component State Update"