How to prevent the render of child components on the parent in react

Advertisements

Here I have created a toggle button re-rendering in parent components and in child components a plus button, and the counter requirement is that the toggle button re-rendering is a toggle button that will hide and show the components, but if any last counter is added, for example, from 0 to 2, after hiding and showing it should remain the same, like 2 and not 0, but the problem is that I am not able to hide the child components, so how do I hide and show the child components and maintain the child state?
Basically, by rendering the parent, I want to keep maintaining the child state value.
parent code is

import React, { useRef, useState, useMemo } from 'react';
import DropDown from './DropDown';

function App() {
  const shouldRenderChild = useRef(true);
  const [hide, setHide] = useState(false);

  const toggleChildRendering = () => {
    shouldRenderChild.current = !shouldRenderChild.current;
    setHide(!hide);
  };

  const MemoizedDropDown = useMemo(() => {
    return shouldRenderChild.current ? <DropDown /> : null;
  }, []);

  return (
    <div>
      <button onClick={toggleChildRendering}>
        Toggle Child Rendering
      </button>
      {MemoizedDropDown}
    </div>
  );
}

export default App;

child code is

import React, { useState } from "react";
export default function DropDown() {
  const [number, setNumber] = useState(0);
  return (
    <>
      <button onClick={() => setNumber(number + 1)}>+</button>
      <div>Child Component{number}</div>
    </>
  );
}

>Solution :

Every time component is mounted or unmounted (using conditional rendering) – state of the component is re-setting itself to default values. So that is your problem, and useMemo hook will not help you here.

To solve your issue you can modify your root css files and add something like .hidden class:

.hidden {
  display: none;
}

Most probably you already have that kind of utility classes in your project. Like d-none for bootstrap or similar.

Next – you need to add a wrapper to your DropDown component, or change the type of root node that is returned by this component to something else than React.Fragment ie <> </> and to apply conditional className on it like this:

className={hide ? 'hidden' : ''}

Here is an example of the solution:

import React, { useState } from 'react';

function DropDown({ className }) {
  const [number, setNumber] = useState(0);
  return (
    <div className={className}>
      <button onClick={() => setNumber(number + 1)}>+</button>
      <div>Child Component: {number}</div>
    </div>
  );
}

export const App = () => {
  const [hide, setHide] = useState(false);

  const toggleChildRendering = () => {
    setHide(!hide);
  };

  return (
    <div>
      <button onClick={toggleChildRendering}>Toggle Child Rendering</button>
      <DropDown className={hide ? 'hidden' : ''} />
    </div>
  );
};

Stackblitz demo

Leave a ReplyCancel reply