MintfreshLindfield
MintfreshLindfield

Reputation: 55

Add class to containing element in React

I have a simple component in react which has two buttons. All I want to do is set a class on the containing div, depending on which button is clicked...

Component (AddOn) js

import React, { useState } from 'react';

  function AddOns(props) {

  const [isSelected, setSelected] = useState(false);
  const [notSelected, setNotneeded] = useState(false);

  const selectAddon = () => {
    setSelected(!isSelected);
    setNotneeded(false);
  }

  const noAddon = () => {
    setNotneeded(!notSelected);
    setSelected(false);
  }

  return (
    <div className="addon">
      <h2>{props.name} cover</h2>
      <h3>£{props.price} per month</h3>
      <p>{props.description} </p>
      <div className="buttons">
        <button role="radio" onClick={selectAddon} className={isSelected ? "selected" : ""}>Select this cover</button>
        <button role="radio" onClick={noAddon} className={notSelected ? "selected" : ""}>I don't need this</button>
      </div>
    </div>
  );
}

export default AddOns;

There's multiple components on a page...

import React, { useState } from 'react';
import AddOn from './AddOns';
import './App.css';

function App() {

  const [extras, setExtras] = useState([
    { name: "Cover 1", price: "1.05", description: "Description goes here", groupName: "lost", groupYes: "group-1", groupNo: "group-2" },
    { name: "Cover 2", price: "2.19", description: "Description goes here", groupName: "abroad", groupYes: "group-3", groupNo: "group-4"},
    { name: "Cover 3", price: "1.53", description: "Description goes here", groupName: "farewell", groupYes: "group-5", groupNo: "group-6" }
  ])

  return (
    <div className="app">
      {extras.map(extra =>(
        <AddOn name={extra.name} price={extra.price} description={extra.description}/>
      ))}
    </div>
  );
}

export default App;

Any help much appreciated from a complete newbie to React!

Upvotes: 0

Views: 476

Answers (3)

michael
michael

Reputation: 4173

You don't need to use 2 states for tracking the button state. Just use one.

Please check below for detail. You can use addonSelected to check which button is selected.

You can set different classname depending on the state like as it is implemented for button.

import React, {useState} from 'react';

function AddOns(props) {
  const [addonSelected, setAddonSelected] = useState(null);

  const selectAddon = () => {
    setAddonSelected(true);
  };

  const noAddon = () => {
    setAddonSelected(false);
  };

  return (
    <div
      className={`addon${
        addonSelected === true
          ? ' selected'
          : addonSelected === false
          ? ' notSelected'
          : ''
      }`}>
      <h2>{props.name} cover</h2>
      <h3>£{props.price} per month</h3>
      <p>{props.description} </p>
      <div className="buttons">
        <button
          role="radio"
          onClick={selectAddon}
          className={addonSelected === true ? 'selected' : ''}>
          Select this cover
        </button>
        <button
          role="radio"
          onClick={noAddon}
          className={addonSelected === false ? 'selected' : ''}>
          I don't need this
        </button>
      </div>
    </div>
  );
}

export default AddOns;

Upvotes: 1

Iosif Bujor
Iosif Bujor

Reputation: 99

My first idea would be to keep className in state and change the state every time the user change selection. Edit: just saw that you are trying to edit classname for a different div, edited the response as well.

 import React, { useState } from 'react';
    
      function AddOns(props) {
    
      const [buttonsClass, setButtonClass] = useState('addon');
      const [notSelected, setNotneeded] = useState(false);
    
      return (
        <div className="addon">
          <h2>{props.name} cover</h2>
          <h3>£{props.price} per month</h3>
          <p>{props.description} </p>
          <div className={buttonsClass}>
            <button role="radio" onClick={()=>{()=>setButtonClass('addon')}} className={isSelected ? "selected" : ""}>Select this cover</button>
            <button role="radio"onClick={()=>{()=>setButtonClass('noAddon')}} className={notSelected ? "selected" : ""}>I don't need this</button>
          </div>
        </div>
      );
    }
    
    export default AddOns;

Upvotes: 0

The KNVB
The KNVB

Reputation: 3844

I suggest adding a variable for the div class, and then change the value in both noAddon and selectAddon function.

Upvotes: 0

Related Questions