I’m developing an application in Next.js, and I encountered unexpected behavior. After reading a JSON file, I create a table with the information from this JSON. For each piece of information, there are additional hidden details that I need to show or hide only if the user clicks on the display buttons – Detail Button and Order Button.
In the image below, I clicked on the details of the first item in the table, and I want it to display details only for the first item. However, it starts displaying details for all other items in the table.
The relevant part of the code looks like this:
// Control visibility of information
const [isVisible2, setIsVisible2] = useState(false);
const toggleVisibility2 = () => {
setIsVisible2(!isVisible2);
}
const [isVisible1, setIsVisible1] = useState(false);
const toggleVisibility1 = () => {
setIsVisible1(!isVisible1);
}
…
// Button to display information
<button className="h-10 px-4 ..." onClick={toggleVisibility1}>
//Verificação para exibir ou não a tabela
{isVisible1 &&
<table>
<thead className="bg-slate-300">
<th className="p-3 text-sm ...">id</th>
<th className="p-3 text-sm ...">Data</th>
These elements are being mapped! There are nested mappings, as within the array of objects, we have objects that, in turn, contain other objects!
// Check to display the table or not
{isVisible1 &&
<table>
<thead className="bg-slate-300">
<th className="p-3 text-sm ...">id</th>
<th className="p-3 text-sm ...">Data</th>
</thead>
{/* Nested map for details */}
{announcements.map(announcement => (
<td>{announcement.ads_id}</td>
{/* Nested table where information needs to be hidden */}
{announcement.order_details.map(detail => (
<td>{detail.name}</td>
))}
))}
</table>
}
The application is deployed here, and the complete code is available on GitHub! The main file in this case is in the next-test/app/components/Announcements.jsx file.
Final Question:
How can I display details only for the clicked button, without activating the visibility of details for all other items?
2
Answers
What you are doing is making every row using the same states for displaying additional info, which changing one will make everything re-render. Not the best approach but you can move the
tr
out and make it a component so they can have their own state:Another approach is to use 2 arrays of booleans, one for the details table and the other for the orders table:
Then when mapping over the announcements you can pass the index:
You can use the index to access the status to determine whether to show the respective table:
The index is passed to the appropriate toggle function so that the right status is updated:
Here’s the updated Announcements.jsx: