How to apply a class on button click using react.js

After spending a few weeks diving into React, I've got the hang of the basic syntax like props and states. However, I'm hitting a roadblock when it comes to connecting certain concepts, especially adding classes when a state changes. My current project involves creating a Simon Says game with four buttons built using a Button component. Initially, these buttons are set to have an opacity of .3 and an active state of false. When clicked, the "active" state should turn true, but I can't seem to add a CSS class to make the button fully opaque. Below is my code:

class App extends Component {
  constructor(){
    super();
    this.state = {
      active: false
    }
  }
  handleClick(){
    this.setState({active: !this.state.active})
  }
  renderButtons(i, f){
    return <Button value={i} className="button" id={f} active= {this.state.active} onClick={() => this.handleClick()}/>
  }
  render() {
    return (
      <div className="App">
        {this.renderButtons("red", "buttonRed")}
        {this.renderButtons("blue", "buttonBlue")}
        {this.renderButtons("green", "buttonGreen")}
        {this.renderButtons("yellow", "buttonYellow")}
      </div>
    );
  }
}

Here's my CSS for reference:

.button{
  width: 100px;
  height: 45px;
  opacity: .3;
  margin: 0 auto;
  margin-bottom: 30px;
}
#buttonRed{
  background: red;
}
#buttonBlue{
  background: blue;
}
#buttonGreen{
  background: green;
}
#buttonYellow{
  background: yellow;
}

I'm hoping to be able to add a class when a button is clicked while still retaining the "button" class on the component. Any suggestions or guidance would be greatly appreciated!

Answer №1

When working with React, there are a few different methods you can use to style elements dynamically. One approach, as suggested by Tudor Ilisoi, involves simply concatenating strings. Another method is to assign an object to the className attribute instead of a string. While this approach may be considered easier, it does require the use of the classnames module. To incorporate this module into your project, you can either run npm install --save classnames or yarn add classnames. After installation, you can import it in your code like this:

import classNames from 'classnames';

You can then utilize it as follows:

<button className={classNames({button: true, active: this.state.active})} />

The first set of curly brackets indicates to React that a dynamic property is being passed, while the second adheres to standard JavaScript syntax for objects. It's important to note that the object must be enclosed within the classNames() function. If the classNames() was declared previously, the implementation could look something like this:

render(){
    const classes = classNames({
        button: true, // always include this class
        active: this.state.active, // only apply this class if the state criteria are met
     });

     return (
          <button className={classes} />
     );
}

Answer №2

Searching for the answer for 2021/2022? Check out this code snippet that demonstrates how to use react hooks to add the class name "app" to a div element when a Toggle class button is clicked.

 import React, { useState } from "react";import "./styles.css";

export default function App() {
  const [isActive, setActive] = useState("false");
  const handleToggle = () => {
    setActive(!isActive);  };
  return (
    <div className={isActive ? "app" : null}>
       <h1>Hello react</h1>
       <button onClick={handleToggle}>Toggle class</button>
    </div>
  );
}

Answer №3

To modify the button's class name, replace className="button" with className={'button ' + f}

The code inside curly braces will be executed as JavaScript and will result in a string

It is important to remember that using curly braces eliminates the need for double quotes around attribute values like ""

After parsing your JSX, React will generate the appropriate HTML attribute such as class="button red".

Answer №4

Give this method a try: you can pass an optional parameter to the renderButtons function, then check it and add it to a class:

...
 renderButtons(i, f, c){
    var cssClass =  c&&c!=""? "button " + c : "button";   
    return <Button value={i} className={cssClass}  id={f} active= {this.state.active} onClick={() => this.handleClick()}/>
  }
...

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

Mastering the Art of Aligning Avatars: Effortless Right Alignment

Here's the updated version of the navigation bar: <nav class="navbar navbar-expand-md navbar-dark bg-dark static-top"> <button class="navbar-toggler" type="button" data-toggle="collapse"> ...

Using Vue3 to conditionally display a child div based on the class of its parent div

Just starting out with Vue, I'm currently experimenting with the active classes feature from this Vue3 carousel plugin. My goal is to only show the text and link divs for the carousel__slide--active class, but at the moment, all carousel__items are di ...

Saving JSON Data into my HTML document

Currently, I am in the process of learning about API's at school which means my knowledge of jQuery is quite limited. However, I have a specific task that involves making an API call and using the retrieved information. Recently, I conducted an ajax ...

"Troubleshooting the issue of nested jQuery Ajax requests failing to execute properly

UPDATE: I'm getting an error saying that my li tag is considered an illegal token. I'm unsure how to resolve this issue as I believed I was appending it within a ul tag I'm tasked with fetching a JSON array of public Github repositories and ...

Section with relative positioning has taken an unexpected position

I'm facing a rather basic issue with positioning a relative div on my webpage. My layout consists of an absolute header that is 100vh tall, containing a headline and caption. Below the header, I have two section elements, both set to a relative posit ...

Looking to add a dynamic drop-down menu to my search bar, similar to Google search

Is there a way to create a dynamic drop-down list where, when a user enters the first letter of a country name, the list displays countries with names starting with that letter? It's similar to the functionality of a Google search bar. The country nam ...

Can this be achieved solely with external URLs and not local ones?

I'm currently facing an issue while trying to create a photo gallery using react-images. Despite having the correct URLs, the photos are not loading on my web app. Every time I switch modalIsOpen:false to true, I encounter the broken image icon. I ha ...

Purpose of triggering another function during an ajax request

I have encountered an issue while working on a project. There is a page with an input field called balance within a div named balanceDiv. This field should not be visible to the admin, so I used ng-show to hide/show the div based on the user's login I ...

How to Create a Responsive Layout with Bootstrap 5: Cards, Grids, and Columns

Struggling to create an HTML layout that resembles the image provided. Despite using Bootstrap 5, I'm having trouble achieving the desired responsiveness. Any assistance or guidance would be greatly appreciated! https://i.sstatic.net/W1Sh0EwX.jpg I ...

Configuring Environment Variables in React App for Azure DevOps Release Pipeline

Our React app in AzureDevOps is built using npm install/npm run, and then we upload the zip file for a release to various stages/environments. To comply with SOX regulations, we aim to maintain a single build/artifact regardless of the environment. I am a ...

Incorrect Matching with Regular Expressions

I'm working on a regular expression to validate a URL. var url = "https://www,google.com"; var urlRegex = /(https|http)?:\/\/(?:\w[\-\w.]+)(?:\/[\-\w+&@#\/%=~_|!:,.;]*)?(?:\?[\-A-Z0-9+&@# ...

What steps should I follow to enable my bot to generate or duplicate a new voice channel?

I needed my bot to either create a new voice server or clone an existing one. The variable "voic" contains the ID of the voice channel. voic.voiceChannel.clone(undefined, true, false, 'Needed a clone') // example from ...

Chrome Devtool reported an error, but the majority of them are in a null file

Currently grappling with an irksome problem in Vue.js. No matter how hard I try, I just can't seem to pinpoint the error. Even when setting a debugger, all it shows is an empty file. Please take a look at the image provided. Any assistance on identify ...

Troubleshooting an issue with window.close in AngularJS

I'm struggling to properly execute the window.close function without encountering the error message below: Scripts may close only the windows that were opened by it. Here is the structure of my application: HTML: <html ng-app="mynewAPP" ng-co ...

Create space in the bootstrap framework between an image and text

I'm trying to increase the space between the title/description and the icon image in my Bootstrap CSS layout. I attempted adding ms-5 to the div tag, but it didn't have the desired effect. NOTE: Please refrain from suggesting margin-right:5px as ...

Error in React Router when using TypeScript

Encountering errors while trying to set up router with React and TypeScript. https://i.sstatic.net/muSZU.png I have already attempted to install npm install @types/history However, the issue persists. Your assistance would be greatly appreciated. Thank y ...

Expanding a CSS div when the content wraps on smaller screens

When viewing the menu on standard screens, everything looks good. However, on smaller screens, the menu items start to wrap which is fine. The only issue is that the containing div #nav does not automatically enlarge along with it. I would like for the div ...

The Android WebView experiencing issues with the functionality of the Hamburger Menu

I'm facing an unusual issue with the Android WebView in my app. The hamburger menu on my website works perfectly fine on my mobile browser, but when I try to open it in the Android WebView, it does not fully expand to show the menu items. I have trie ...

There is a vast expanse separating the header of the page and the navigation bar

Hello! I'm trying to figure out why there is a huge space between the top of the page and the navbar on this site: . I've included the CSS and HTML below. Any help would be greatly appreciated, thank you! HTML: <!DOCTYPE html> <html> ...

Simplifying complex callback structures

In this scenario, I have created a callback function to handle object data processing. function (err, data) { var finalResult; if (data && data.result instanceof Array) { finalResult = data.result.map(function (value) { if ...