I have been trying to wrap my head around why my ternary operator isn't being hit when I have set isOpen
to true.
I have this in my component.
{isOpen ? (
<div>
<div className="mt-6 flex flex-col">
<button className="mb-1 rounded bg-blue-500 px-4 py-3 capitalize text-white duration-100 ease-in-out hover:bg-blue-700">
<span className="text-center">edit</span>
</button>
<button
className="rounded bg-red-500 px-4 py-3 capitalize text-white duration-100 ease-in-out hover:bg-red-700"
onClick={deleteContact}
>
<span className="text-center tracking-wide">Bye!</span>
</button>
</div>
</div>
) : (
<div>
<div className="mt-6 flex flex-col">
<button className="mb-1 rounded bg-blue-500 px-4 py-3 capitalize text-white duration-100 ease-in-out hover:bg-blue-700">
<span className="text-center">edit</span>
</button>
<button
className="rounded bg-red-500 px-4 py-3 capitalize text-white duration-100 ease-in-out hover:bg-red-700"
onClick={() => setIsOpen(true)}
>
<span className="text-center tracking-wide">delete</span>
</button>
</div>
</div>
)}
When I click the following button:
<button
className="rounded bg-red-500 px-4 py-3 capitalize text-white duration-100 ease-in-out hover:bg-red-700"
onClick={() => setIsOpen(true)}
>
<span className="text-center tracking-wide">delete</span>
</button>
It seems the ternary operator isn't being fired or maybe the isOpen
isn't being set to true.
Its this delete button here:
But when clicking the <ShowContact />
just gets removed from the tree instead of hitting the ternary.
The whole repo is here if you want to replicate https://github.com/mrpbennett/contact_fastapi/tree/react-fe
I have resolved this by moving my click handler ... as
The toggle action(setShowContact) of contact detailed is linked to div tag (container of whole contact info).
{contacts.map((contact) => (
<div key={contact.id}>
{showContact === contact.id ? (
<ShowContact contactId={contact.id} open={true} />
) : (
<div
className="border-b border-gray-200 p-4 py-2 text-left capitalize text-gray-700 hover:bg-gray-200"
onClick={() =>
setShowContact((show) =>
show === contact.id ? null : contact.id
)
}
>
<span className="font-bold">{contact.first_name}</span>{' '}
{contact.last_name}
</div>
)}
</div>
))}
I think you need to get rid of line 14 window.location.reload(true);
in your "ShowContact" component. That is causing your whole application to reload, which is then reinitializing "isOpen" state to be false again.
Sounds like the parent component is re-instantiating the child component ShowContact
. The parent needs to memoize whatever renders ShowContact
to avoid it being recreated from scratch, causing isOpen to initialize to false.
There are numerous ways that can occur, such as assigning the render result to a variable and inserting it in the JSX:
const showContactRender = ( <ShowContact ... /> );
return (
<div>
...
{showContactRender}
...
</div>
);
In the above example, every time a re-render is triggered in the parent, it recreates the component stored in showContactRender. useMemo
avoids recreating it if its inputs don't change. However a better way would be to avoid that if possible and insert <ShowContact>
directly into the return JSX.
Note that the problem outlined above may not be in the direct parent, but the parent's parent, or any component above it. Set breakpoints everywhere to see how often it gets re-rendered.