What is the best approach to changing the color of an item in a cart once it has been selected?

Recently, I've been facing an issue with changing the color of an item after it has been added to the cart. Below are my functions for adding and removing items from the cart:

function addToCart(newItem) { 
        cartItems.map(item => newItem.type === item.type && removeFromCart(item)) 
        setCartItems(prevItems => [...prevItems, newItem])
    }

function removeFromCart(itemToRemove) { 
    setCartItems(prevItems => prevItems.filter(item => 
       `${item.id}-${item.type}` !== `${itemToRemove.id}-${itemToRemove.type}`)) 
    }

I have a component called 'Option' which displays each service within its structure:

const serviceElements = servicesList.map(service => 
          <Service key={service.id} 
                   id={service.id} 
                   name={service.name} 
                   type={service.type} 
           /> )

     return (
        <div className={`Options-${context.theme}`} >
            <ul>
                {serviceElements}
            </ul>
        </div>
    )

This is how the 'Service' component looks like:

<>
      <li onClick={() => { context.cartItems.includes(props) 
                           ? context.removeFromCart(props) 
                           : context.addToCart(props)}}>
                {props.name}
      </li>
</>

My attempt at adding a class to the 'Service' component resulted in all elements in the displayed list changing color, instead of just the specific one I wanted to change:

<>
      <li 
          className={context.cartItems.includes(props) ? "notInCart" : "inCart"}  
          onClick={() => { context.cartItems.includes(props) 
                          ? context.removeFromCart(props) 
                          : context.addToCart(props)}}>
                {props.name}
      </li>
</>

I have experimented with different styling options in my SCSS file but cannot pinpoint the exact source of the problem:

.Options-light {
  @extend .TimeGrid-light;
  ul {
    .inCart {
      background-color: blue;
    }
    .notInCart {
      background-color: red;
    }
  }
}

//and also tried

.Options-light {
  @extend .TimeGrid-light;
  .inCart {
    background-color: blue;
  }
  .notInCart {
    background-color: red;
  }
}

It's challenging to identify where the issue lies exactly.

Answer №1

In order to achieve this, you will require a state implementation.

class ServiceComponent extends Component {
  constructor(props) {
    super(props);
    // Binding 'this' in the callback is essential for proper functionality
    this.addToCart = this.addToCart.bind(this);
    this.state = {
      active: false
    };
  }

  addToCart(context) {
    if (context.cartItems.includes(this.props)) {
        context.removeFromCart(this.props);
    } else {
        context.addToCart(this.props);
    }

    this.setState({
      active: !this.state.active
    });
  }

  render({ context }) {
    return (
      <>
        <li className={this.state.active ? "notInCart" : "inCart"} onClick={() => this.addToCart(context)}>
          {props.name}
        </li>
      </>
    )
  }
}

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

Populate a table dynamically in JavaScript using a variable

I have a table with IDs such as r0c1 = row 0 column 1. I attempted to populate it using the following script, but it doesn't seem to be functioning correctly: var data = new Array(); data[0] = new Array("999", "220", "440", "840", "1 300", "1 580", " ...

How can a key press be simulated without specifically targeting an element?

Is it possible to simulate a key press without targeting any specific element? I found this code snippet: var press = jQuery.Event("keypress"); press.ctrlKey = false; press.which = 75; $("whatever").trigger(press); The above code is used to simulate pres ...

Modify the properties of a particular component

I have an array of rooms filled with data: const room = (<Room points={points} scene={this.scene} key={this.rooms.length} keyV={this.rooms.length} />) this.roomData.push(room); For example, I now have 3 rooms each with their ...

Run Javascript code if a specific CSS class is present on an element

Whenever a user enters an incorrect value into a textbox on my page, an error message is displayed within a div with the class 'validation-errors'. I'm looking for a solution to trigger a javascript function (which adds a CSS property to a ...

Identifying and capturing changes in child scope events or properties in Angular

I am encountering an issue with my form directive where I need to intercept ng-click events nested within varying child scopes of the form element. However, I am struggling to hook into these events or child scope properties in a generic way. For demonstr ...

Unable to get Angular ng-click to function properly when used in conjunction with $

I am encountering an issue with triggering a click event in my Angular app using code similar to the example below. Can anyone help me understand why the event is not being triggered? var app = angular.module("myApp", []) app.directive('myTop', ...

The node.js express app.get and app.post are currently malfunctioning

I have encountered an issue with my Express JS code. Currently, I am using app.use and everything works perfectly. However, when I try to use app.post or app.get instead of app.use, the code stops working and my IDE (WebStorm) does not recognize these meth ...

Step-by-step guide to creating a dynamic button that not only changes its value but also

I am trying to implement a translation button on my website that changes its value along with the text. Currently, I have some code in place where the button toggles between divs, but I am struggling to make the button value switch as well. Given my limit ...

Establishing the sizing of an element across various breakpoints

I'm having trouble setting up varying widths based on different breakpoints. For instance, the code below will be used for all breakpoints: <nav class="navbar-nav w-75 ml-md-4"> ... a select element </nav> But how do I enable w-100 for s ...

Encountering the error message "Cannot GET /" in a NodeJS Express

I've been experimenting with various approaches to resolve this issue, ranging from app.use(express.static(__dirname + "public")) to res.render. It seems to function correctly in my terminal environment but fails when I try to access it locally. Can a ...

The use of setState clashes with the getDerivedStateFromProps method

import React, { Component } from "react"; export interface MyComponentProps { display: boolean; } export interface MyComponentState { display: boolean; } export default class CustomComponent extends Component<MyComponentProps, MyComponen ...

Exploring Ways to Retrieve Property Names in AngularJS JSON

I need help finding a way to use the property name as the table header in my code example below: <table> <th ng-repeat="auditorium in auditoriums"> {{ auditorium.NAME }} </th> <tbody ...

When using jQuery's POST method, the "done" event is triggered, however, no data is being sent

I've been working on implementing AJAX form submission and wrote a function to handle it when the button is clicked: function putUser() { $('button#putUser').on('click', function() { var user = $('input#user' ...

What is the method to retrieve content from a different domain using .load()?

When I try to retrieve data from a different domain using .load() or other jQuery ajax functions, it doesn't seem to work. However, accessing URLs on my own domain works perfectly fine. I've heard about a workaround involving PHP and setting up ...

Exploring the capabilities of utilizing getServerSession in Next.js 13 along with API routes located in the

I am utilizing next-auth and attempting to obtain serverSession on a server component. I am using Next.js 13 beta with the App directory and the API directory located within the App directory. As per the next-auth documentation, this is the method recommen ...

The input field for Google Places Autocomplete now includes the code "display: none"

I'm currently working on an AngularJS application and have implemented this directive to enable Google Maps API places autocomplete in the input field below. <div> <input type="text" autocomplete="off" g-places-autocomplete ...

Rotational orientation of a progress circle image in SVG

I am currently working on developing a circular progress bar, similar to the one shown in the image below. The progress of this bar is determined by percentages and it moves around the circle accordingly. I have managed to get the progression moving, b ...

Mastering the Art of Line Breaks in WordPress

I am looking for a way to break a WordPress site title over two lines at a specific point in the text. Since the WordPress content filter 'wpautop' disables the ` ` tag (also known as ` ` or ` `), I'm wondering what the best alternative ...

Prevent event propagation when clicking on an Autocomplete material UI component within an accordion section

I am facing an issue with adding an Autocomplete component inside an AccordionSummary. Whenever I click on it, the accordion expands and enters a focus state. I have tried to stop the propagation of events, but unfortunately, it has not been successful. ...

Exploring Angular2: Understanding how to retrieve an object with an unknown key

I am trying to showcase a specific value from different objects within a template. The path of the desired value depends on the object being referenced. For example: let obj = { "a": "a", "b": { "1": "1", "2": "READ ME" } } let ...