Parent setState works yet setState inside child does not

Viewed 31

I have the following code structure (simplified):

This is the parent:

 //code...

 const {handleClick} = useClick;

 <ul>
   {actions.map((action: string) => (
      <li onClick={() => handleClick()} key={uuidv4()}>
         {getAction(action, id)}
      </li>
   ))}
</ul>

getAction is the following:

export const getAction = (
  action: string,
  id: number | string
): JSX.Element | null => {

   switch (action) {
    case Actions.submit_recall: {
      return <Report {...{ id }} />;
    }

   //code...
};

Report is the following:

export const Report = ({ id }: ReportType): JSX.Element | null => {
  const [isModalOpen, setIsModalOpen] = useState<boolean>(false);

  return (
    <>
      <div onClick={() => setIsModalOpen(true)}>Report a Recall</div>

      <Modal
        open={isModalOpen}
      >

     //code...

)};

Some context: When you click on the li element, is supposed to both hide the ul on the parent and open the modal inside the Report component. Yet currently it only hides the ul element.

When I click on the li element inside the parent, the function handleClick does get called, yet clicking on the div inside the Report component does not trigger setIsModalOpen(). I tried console.log a value when clicking on the div, and it does work...

The handleClick is nothing more than:

const handleClick = () => setClick(!click);
      <div
        onClick={() => {
          console.log("hi");
          return setIsModalOpen(true);
        }}

enter image description here

What I don't follow is that, if I eliminate or comment the handleClick inside the parent, the function setIsModalOpen inside Report works as intended.

I had suspected that when I successfully hid the 'ul' element, I was also hiding the modal since is inside the parent yet I confirmed that is not the case since I manually hide the ul (with CSS, no react logic), manually open the modal. Also, was checking the react profiler extension.

Bottom line, when the handleClick function runs, setIsModalOpen function does not. Why? ...the desired behavior is when clicking on the li element inside the parent, the ul should hide (alongside the li), and the modal should stay open.

Sorry if I wasn't specific enough, thanks for the help.

1 Answers

Since this comment ended up as the answer:

I'm guessing key={uuidv4()} causes a new UUID to be generated every render which means your components are always mounted anew.

Local state would be wiped out because you have a new key/new component instance.

Remove the key for a moment and see what happens (default is index).

It should be a persisted key like an ID, or React 18 useId() or index if you understand what it means to have an index key (makes sense if elements in your map never change order)

Related