Prevent the Icon in Material UI from simultaneously changing

I'm working on a table where clicking one icon changes all icons in the list to a different icon. However, I want to prevent them from changing simultaneously. Any suggestions on how to tackle this issue?

Code:

import React from 'react';
import {makeStyles, Theme} from '@material-ui/core/styles';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableContainer from '@material-ui/core/TableContainer';
import TableHead from '@material-ui/core/TableHead';
import TablePagination from '@material-ui/core/TablePagination';
import TableRow from '@material-ui/core/TableRow';
import TableSortLabel from '@material-ui/core/TableSortLabel';
import IconButton from '@material-ui/core/IconButton';
import Tooltip from '@material-ui/core/Tooltip';
import FilterListIcon from '@material-ui/icons/FilterList';
import FavoriteBorderOutlinedIcon from '@material-ui/icons/FavoriteBorderOutlined';
import FavoriteOutlinedIcon from '@material-ui/icons/FavoriteOutlined';
...

export default function Table() {
    ...
        const [isFavorite, setIsFavorite] = React.useState(false);
    ...
    return (
        ...
                                    return (
                                        <TableRow
                                            hover
                                            tabIndex={-1}
                                            key={row.name}>
                                            <TableCell>{row.name}</TableCell>
                                            ...
                                            <TableCell>
                                                    <IconButton onClick={() => setIsFavorite(!isFavorite)}>
                                                        {isFavorite ? <FavoriteOutlinedIcon color="secondary"/> :  <FavoriteBorderOutlinedIcon color="action"/> }
                                                    </IconButton>
                                            </TableCell>
                                               ...
    );
}

Answer №1

Your state isFavorite is toggling with every click. To achieve the desired functionality, create a favorite property on an icon object as shown below:

const [iconData, setIconData] = useState([
  {icon: someIcon, id: 1, isFavorite: false},
  {icon: diffIcon, id: 2, isFavorite: false},
  {icon: thirdIcon, id: 3, isFavorite: false}
])

In the return statement, map over the iconData objects:

iconData.map(icon => (
<TableCell key={icon.id}>
    <IconButton onClick={() => iconFavChange(icon.id)}>
      {icon.isFavorite ? <FavoriteOutlinedIcon color="secondary"/> :  
           <FavoriteBorderOutlinedIcon color="action"/> }
     </IconButton>
</TableCell>
))

Function to handle icon change:

const iconFavChange =(id)=> {
 let updatedIconData = iconData.map(icon => icon.id === id ? icon.isFavorite = !icon.isFavorite : icon)
// Map over existing state data and toggle the isFavorite property if the id matches
 setIconData(updatedIconData)
}

Edit:

  1. The row data was stored outside the component, so I added a slice of state using React.useState(rows) to set row as the initial state.
const [data, setData] = React.useState(rows);
  1. An isFavorite property was added to your row data.
isFavorite: boolean;
  1. A favorite handler function was included to toggle the isFavorite property by looping over the data based on the name passed as an argument.
const handleFavoriteToggle = name => {
    console.log(name);
    let updatedData = data.map(row => {
      if (row.name === name) {
        row.isFavorite = !row.isFavorite;
      }
      return row;
    });
    setData(updatedData);
};
  1. The icon component was updated accordingly.
<IconButton onClick={() => handleFavoriteToggle(row.name)}>
    {row.isFavorite ? (<FavoriteOutlinedIcon color="secondary" />)
                    : (<FavoriteBorderOutlinedIcon color="action" />)}
</IconButton>
  1. The parameter was changed from 'row' to our data slice of state.
<TableBody>
            {stableSort(data, getComparator(order, orderBy))
              .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
              .map((row, index) => {

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The token endpoint in Nuxtjs auth module's configuration for auth strategies is not being triggered

Our system has two important endpoints, namely /auth and /token. The endpoint /auth is responsible for providing the authorization code required to call /token in order to obtain an access token. The utilization of NuxtJS has made the auth module a prefer ...

What is the process for verifying a checkbox after it has been selected?

I simplified my code to make it easier to understand const [factor, setfactor] = useState(1); const [nullify, setNullify] = useState(1); const Price = 10; const Bonus = 15; const finalPrice = (Price * factor - Bonus) * nullify; // start ...

Mistake in the hovering positioning within the WordPress theme

I've encountered a hover issue on my website that I'm trying to resolve. Every time I hover over a product, the product description appears underneath it instead of on top, and I can't seem to find a solution: The site is using the sentient ...

What is the best way to utilize the node.js module passport-google?

I'm currently working on a node.js web application that prompts users to sign in using their Gmail account. While following instructions provided at this website, I modified the URL from www.example.com to localhost and launched the application. Howev ...

Exploring Next.js: A Guide to Implementing Browsing History in Your Application

Struggling to add entries to browser history when using Next.js's Link property for page navigation. Unable to push history entry, leading to incorrect page location in my application when going back. Any ideas on implementing this feature in Next.js? ...

Displaying a list within a circle that elegantly animates, and then, after two full rotations, magically morphs

Can icons be displayed in a circle and after 1,2 rotations, revert back to the list view? https://i.sstatic.net/p4Jxm.png If so, when it forms after 1,2 rotation, it should resemble a line. https://i.sstatic.net/uJW24.png In summary, looking for a CSS3 ...

Getting a jQuery alert on iOS devices: A step-by-step guide

The notification using <span class="close">&times;</span> functions perfectly on all desktop browsers, but unfortunately fails to trigger on mobile devices ... When attempting to view the page on an iPhone, the <span class="close">&am ...

Ensure that the display is set to block to stack the input elements on top of each other

I am attempting to grasp the functionality of CSS display property and experimented with this basic HTML code: <div> <form className="container" action=""> <input name="fName" placeholder="First Name" type="text" value={props.fNam ...

confirmation box for deleting a row in a grid view

I am looking to enhance the delete confirmation box on my Gridview delete function. Currently, I am using a basic Internet Explorer box for confirmation but I want to display a more stylish confirmation box. Here is the JavaScript code snippet within my gr ...

Responding to a tweet with the help of twit and Node.js

Utilizing the Twit Node.js API has presented me with a challenge. I am attempting to reply to a tweet that contains a specific keyword. My goal is for my response tweet to appear nested underneath the original tweet, much like how replies function on socia ...

Tips on incorporating a changing variable into a JavaScript Shader

I have successfully created a primitive sphere using THREE.SphereGeometry and applied a displacement shader to give it a bumpy effect. My goal now is to animate the scale of the bumps based on input volume from the microphone. Despite my efforts, I am stru ...

Unchecked checkbox displays as checked in UI

I am facing an issue with checking checkboxes using JavaScript. Even though the checkbox appears to be checked in the program, it does not reflect the updates on the user interface. If anyone has a solution for this, please share. <!DOCTYPE html> ...

How to Implement Loading Image with CSS

I have customized the CSS code below to style a div element that showcases a responsive image. .my-img-container { position: relative; &:before { display: block; content: " "; background: url("https://lorempixel.com/300/160/") ...

The type '{}' cannot be assigned to type 'IntrinsicAttributes & FieldsProp'. This error message is unclear and difficult to understand

"The error message "Type '{}' is not assignable to type 'IntrinsicAttributes & FieldsProp'.ts(2322)" is difficult to understand. When I encountered this typeerror" import { useState } from "react"; import { Card } fr ...

The function in jQuery that can be used to hide a <div> when clicked

I am facing a problem with my jQuery code that is supposed to remove/hide a specific div. Despite checking various examples, I can't seem to make it work properly. This issue arises in the context of jQuery on Drupal 7. The live site where this proble ...

Persist user input even after reloading the page

In order to enhance the user experience, I would like to implement a feature where the data entered by the user is preserved even if they refresh, reload, or close the page. This includes retaining the selections made in the select elements. Additionally, ...

Retrieving information from the backend using JavaScript

Utilizing devexpress JS Charts requires data to be in the format: [{ category: 'Oceania', value: 35 },{ category: 'Europe', value: 728 }] To achieve this format, I convert a DataTable to JSON in my backend code after running queries b ...

Why isn't my heading showing up as expected in my document?

Can anyone help me understand why my title appears so low on certain screens? I've previously tried removing the negative margin when the title was hidden, but now it's positioned too far down. Here is the link to my webpage: ...

Using Angular to handle routes with a specific domain prefix

Let's say I own the domain https://example.com and I'd like to create a subdomain specifically for my blog, like this: https://blog.example.com. How would you handle the routing for this scenario using Angular? ...

Position the final list item in the column on the left side

Currently, I am facing an issue with creating spacing between li elements in a column layout. The problem arises when the last li in the column does not align to the far left edge of the column width. Take a look at the screenshot below for reference: Bel ...