How to Alter Button Color upon Click in React with Bootstrap?

I'm working on implementing a thumbs up and thumbs down feature similar to Reddit's upvote and downvote system.

The goal is to change the color of the object to green when the thumbs up is clicked and to red when the thumbs down is clicked.

However, I need to prevent the user from clicking thumbs up twice and reverting the color from green to default white. Any suggestions?

class VoteCounter extends React.Component {
    constructor(props) {
        super(props);
        this.state = {counter: 0}
    }

    increment = (e) => {
        e.preventDefault();
        this.setState({
            counter: this.state.counter + 1
        });
    }

    decrement = (e) => {
        e.preventDefault();
        this.setState({
            counter: this.state.counter - 1
        });
    }

    render() {
        return (
            <div className="voting">
                {this.state.counter}
                <button className="upvoteBtn" type="submit" onClick={this.increment}>
                    <i className="fa fa-thumbs-up ml-2 mr-2"/>
                </button>
                <button className="downvoteBtn" type="submit" onClick={this.decrement}>
                    <i className="fa fa-thumbs-down ml-2 mr-2"/>
                </button>
            </div>
        )
    }
}

Answer №1

This code snippet provides a solution where clicking either the up or down button will disable both buttons. You can also integrate your own counter function within the handleUp and handleDown methods:

class CustomComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      colorUp: 'secondary',
      colorDown: 'secondary',
      clicked: false
    };

    this.handleUp = this.handleUp.bind(this);
    this.handleDown = this.handleDown.bind(this);
  }

  handleUp(event) {
    if (this.state.clicked === false) {
      this.setState({
        colorUp: 'success',
        clicked: true
      });
    }
  }

  handleDown(event) {
    if (this.state.clicked === false) {
      this.setState({
        colorDown: 'danger',
        clicked: true
      });
    }
  }

  render() {
    return (
      <div>
        <ReactBootstrap.Button className='ml-3' variant={this.state.colorUp} onClick={this.handleUp} disabled={this.state.clicked}>Up</ReactBootstrap.Button>
        <ReactBootstrap.Button className='ml-3' variant={this.state.colorDown} onClick={this.handleDown} disabled={this.state.clicked}>Down</ReactBootstrap.Button>
      </div>
    );
  }
}

ReactDOM.render(
  <CustomComponent />,
  document.getElementById('root')
);
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/react-bootstrap@next/dist/react-bootstrap.min.js" crossorigin></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css" crossorigin="anonymous">

<div id="root">

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

Interacting between client and server with the help of JavaScript and websockets

As someone new to Javascript, I am eager to learn about the steps and initial codes needed to establish a connection between the client side and the server side using JS and websockets. ...

Guide to sending both JSON data and form data in a single request using Laravel 9

I am working on a form where I need to input multiple images that will be converted into JSON format. The HTML for my form: create.blade.php <form method="post" action="{{ route('m_announcement.store') }}" enctype="mu ...

Ways to swap out element within ViewContainerRef in Angular

I am currently expanding my knowledge of Angular and I have encountered a challenge regarding dynamically creating components and swapping them within a single container. Here is the setup: <ng-container #container></ng-container> Here are the ...

The battle between Hover, Focus, and Blur modes intensifies

My goal is to implement 4 different effects on an element: When hovering over the element. When moving away from the element. When focusing on the element. When blurred. However, I'm encountering a conflict where when I focus on the element, the ...

Hosting React on IIS without refreshing the DOM

Currently developing a React Application with 4 pages. The routing works perfectly when running locally, all pages are rendered properly. However, the same cannot be said for IIS. I have set up a 'dist' folder and mapped it to the IIS directory. ...

Prevent Duplicate Service Instances in Angular

After doing some thorough research online, I've identified the root of my issue: multiple instances of a particular service are being created. I need assistance in pinpointing and rectifying this problem within my code. The secondary service is depen ...

Developing an npm module encapsulating API contracts for seamless integration with front-end applications using Typescript

I am curious if Typescript supports this specific idea, and I could use some advice on how to make it work. In my project, there's a frontend application and a backend REST API with clear contract classes for Inputs and Outputs. These classes outline ...

What steps should I take to ensure that this JSON.stringify function functions as intended?

I'm facing a minor challenge in formatting my arrays into the desired JSON structure. Here's the code I've used: var arrData = [{label:Test,value:199.12}, {label:Test2,value:1024}] var data = []; for (var i = 0; i < arrData.length ...

Generating dynamic div elements using jQuery

I am currently working on developing a button that will automatically generate pre-formatted divs each time it is clicked. The divs consist of forms with fields that should already be populated with data stored in JavaScript variables. Example: <d ...

The div extends beyond its parent due to its height

This issue is concerning. https://i.stack.imgur.com/on8t9.jpg The border of the div extends beyond the red line. I have set this for body and html: html { height: 100%; } ::-webkit-scrollbar { width: 0px; background: transparent; /* make scrol ...

Creating a private variable in Javascript is possible by using getter and setter functions to manage access to the

Is this the correct way to simulate a private variable? var C = function(a) { var _private = a + 1; // more code... Object.defineProperties(this, { 'privateProp': { get: function() { return _privat ...

External vendor scripts such as JavaScript and jQuery are not functioning properly after being rendered in a ReactJS environment

I am currently developing a frontend web app using ReactJS. I obtained a template from W3layout that is built with HTML5, CSS3, and custom JS files, along with various third-party/vendor plugins like nice-select, bootstrap, slik, owl-carousel, etc. Despit ...

Tips for retrieving data from a concealed input within a div that is being looped through in Angular.js

Currently, I have a controller that sends data to the UI and uses the ng-repeat directive to map them. My next goal is to bind this data with a hidden input form and then send it to another function in the controller when a click event occurs. Any tips on ...

Measuring JSON data with PHP through asynchronous requests

Looking to retrieve a specific count from a json dataset. Here is an example json format: { "tickets": [ { "url": "https://asd.zendesk.com/api/v2/tickets/1.json", "id": 1, "external_id": null, "via": { "channel": "sa ...

Using React Router version 5 along with history but encountering a problem where no content is displayed during

Struggling to figure out what I'm missing here. My routing was functioning well until I switched from BrowserRouter: import { BrowserRouter as Router } from 'react-router-dom' Now, I need to navigate programmatically outside of my componen ...

How can you align two div elements side by side, if the first div is spanning across two lines?

I'm looking to position two divs next to each other, with the second div starting right where the first one ends. I came across a similar question on Stack Overflow, but unfortunately, it didn't have the answer I needed. <div id="wrapper"> ...

Error in Typescript index: iterating over properties of a typed object

My scenario involves an interface that extends multiple other interfaces from an external library: interface LabeledProps extends TextProps, ComponentProps { id: string; count: number; ... } In a different section of the codebase, there is an ...

Issue with retrieving date from MySQL column being a day behind in JavaScript (Node.js)

I currently have a Node.js server up and running as the API server for a service that I am developing for a company. The dates stored in the MySQL server that it connects to are related to event start times. Insertion of these dates is flawless, and when ...

When using jqueryprint.js to print from Firefox browser, an additional blank page appears before the content

Seeking assistance in printing a section of an HTML page using PHP with a large header space for empty space after printing. Despite multiple attempts, achieving the desired result in Chrome, but facing issues with Firefox, which adds an additional page be ...

Is it possible to use @ViewChild to target an element based on its class name?

The author of this article on Creating Advanced Components demonstrates selecting an element by creating a directive first: @Directive({ selector: '.tooltip-container' }) export class TooltipContainerDirective {} Then, the author uses this d ...