Home > Software engineering >  how to add class and remove class from buttons in react?
how to add class and remove class from buttons in react?

Time:09-18

I have 20 buttons and i wanted to apply class .active on the button which is clicked and the rest will inactive. Suppose i clicked on button one then i want to add active class to button one and then when i clicked on button two then button two will get active class and active class removed from button one.

import React from "react";
const PaginationButtonsList = (props) => {

    const handleClick = (event) =>{
   
    }
  return (
    <div className="pagination-buttons-list">
      <button onClick={handleClick} id="button-1">1</button>
      <button onClick={handleClick} id="button-2">2</button>
      <button onClick={handleClick} id="button-3">3</button>
      <button onClick={handleClick} id="button-4">4</button>
      <button onClick={handleClick} id="button-5">5</button>
      <button onClick={handleClick} id="button-6">6</button>
      <button onClick={handleClick} id="button-7">7</button>
      <button onClick={handleClick} id="button-8">8</button>
      <button onClick={handleClick} id="button-9">9</button>
      <button onClick={handleClick} id="button-10">10</button>
      <button onClick={handleClick} id="button-11">11</button>
      <button onClick={handleClick} id="button-12">12</button>
      <button onClick={handleClick} id="button-13">13</button>
      <button onClick={handleClick} id="button-14">14</button>
      <button onClick={handleClick} id="button-15">15</button>
      <button onClick={handleClick} id="button-16">16</button>
      <button onClick={handleClick} id="button-17">17</button>
      <button onClick={handleClick} id="button-18">18</button>
      <button onClick={handleClick} id="button-19">19</button>
      <button onClick={handleClick} id="button-20">20</button>
    </div>
  );
};

export { PaginationButtonsList };

CodePudding user response:

I assume that you don't want a button with just generic numbers for text. So you will need to:

  1. create an array list with all text that you want to set to the button
  2. Then render all of it through the map and bind the onClick event to take the index
  3. on click you should set that index in state and check which button has that index so set it to active

.

import React, {useState} from "react";

/* Change this number to any text and add as many as you need */
let buttonText = ['1','2','3','4','5']

const PaginationButtonsList = (props) => {
    const [activeIndex, setActiveIndex] = useState(-1)

    const handleClick = (value) =>{
           setActiveIndex(value)   
    }
  return (
    <div className="pagination-buttons-list">
      {buttonText.map((text,index)=> (
           <button onClick={()=>handleClick(index)} class={index === activeIndex ? "active" :""} id={`button-${index}`}>{text}</button>
        )
    </div>
  );
};

export { PaginationButtonsList };

CodePudding user response:

One way of approaching this would be to create an array of button objects that you can use to configure your component. Each button object in the array would have the shape { id: number, text: string, active: boolean } that defines it. You can that add that configuration to state.

When a button is clicked you reset the active values of each button (by updating a deep-copy the current state), update the active value of the clicked button, and finally create a new state with the updated data. That new state will be reflected in the component when it's re-rendered.

This method also has the advantages that 1) you encapsulate the button config in one place without the need for separate states, and 2) you don't need to hard-code all the buttons in the JSX - you can map over the button configuration to create an array of buttons using a useful Button component.

const { useState } = React;

// Pass in the button config
function Example({ btnConfig }) {

  // Set state with the config
  const [ btns, setBtns ] = useState(btnConfig);

  // When a button is clicked grab its id from its dataset,
  // make a deep copy of the state resetting all of the active
  // values for each button to false, find the index of the button
  // that was clicked, and then set its active value to true.
  // Finally update the state to re-render the component
  function handleClick(e) {
    const { id } = e.target.dataset;
    const reset = btns.map(btn => ({ ...btn, active: false }));
    const index = reset.findIndex(btn => btn.id ===  id);
    reset[index].active = true;
    setBtns(reset);
  }

  // `map` over the state and create JSX using a 
  // Button component passing down the properties from
  // the objects in state as well as a reference to the
  // `handleClick` function
  return (
    <div>
      {btns.map(btn => {
        const { id, text, active } = btn;
        return (
          <Button
            key={id}
            id={id}
            active={active}
            text={text}
            handleClick={handleClick}
          />
        );
      })}
    </div>
  );

}

// Accepts the button props and returns a button. If
// the active value is true then apply the "active" class
function Button({ id, text, active, handleClick }) {
  return (
    <button
      data-id={id}
      onClick={handleClick}
      className={active && 'active'}
    >{text}
    </button>
  );
}

// Create a button config - an array of button of objects
const btnConfig = Array.from({length: 10}, (_, i) => {
  const id = i   1;
  return { id, text: id, active: false }; 
});

// Pass in the button config to the component
ReactDOM.render(
  <Example btnConfig={btnConfig} />,
  document.getElementById('react')
);
button { margin-right: 0.5em; font-size: 1.2em; border-radius: 5px; padding: 0 0.4em; }
button:hover { cursor: pointer; background-color: #cdcdcd; }
button.active { background-color: lightgreen; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>

CodePudding user response:

You only need to save a single integer of state, the index corresponding to the active button -

function App({ buttons = [] }) {
  const [active, setActive] = React.useState(-1)
  const toggle = index => event => setActive(index)
  return <div>
    {buttons.map((b, key) =>
       <button
         className={active == key && 'active'}
         onClick={toggle(key)}
         children={b}
       />
    )}
  </div>
}

ReactDOM.render(
  <App buttons={["           
  • Related