¿Cómo puedo alternar una clase al hacer clic con React?

6 minutos de lectura

avatar de usuario
Pedro Flanagan

Estoy tratando de averiguar cómo alternar una clase activa al hacer clic para cambiar las propiedades de CSS.

Mi código está abajo. ¿Alguien puede aconsejarme cómo debo hacer esto? Sin crear un nuevo componente para cada artículo, ¿es posible hacer esto?

class Test extends Component(){

    constructor(props) {
  
    super(props);
    this.addActiveClass= this.addActiveClass.bind(this);
  
  }
  
  addActiveClass() {
    
    //not sure what to do here
    
  }

    render() {
    <div>
      <div onClick={this.addActiveClass}>
        <p>1</p>
      </div>
      <div onClick={this.addActiveClass}>
        <p>2</p>
      </div>
        <div onClick={this.addActiveClass}>
        <p>3</p>
      </div>
    </div>
  }

}

avatar de usuario
cssko

Usar estado. Ver el Reaccionar documentos.

class MyComponent extends Component {
    constructor(props) {
        super(props);
        this.addActiveClass= this.addActiveClass.bind(this);
        this.state = {
            active: false,
        };
    }
    toggleClass() {
        const currentState = this.state.active;
        this.setState({ active: !currentState });
    };

    render() {
        return (
            <div 
                className={this.state.active ? 'your_className': null} 
                onClick={this.toggleClass} 
            >
                <p>{this.props.text}</p>
            </div>
        )
  }
}

class Test extends Component {
    render() {
        return (
            <div>
                <MyComponent text={'1'} />
                <MyComponent text={'2'} />
            </div>
        );
    }
}

  • ¿Hay alguna manera de hacer esto sin crear un componente adicional?

    – Peter Flanagan

    6 de marzo de 2017 a las 16:39

  • Si desea dividir componentes complejos en componentes más pequeños, consulte facebook.github.io/react/docs/…

    – cssko

    6 de marzo de 2017 a las 16:43


  • He dividido el componente, pero esto aún agrega active a cada elemento al hacer clic. Solo quiero que un elemento tenga una clase activa.

    – Peter Flanagan

    06/03/2017 a las 17:32

  • Esto no se puede llamar clase ‘activa’ alternada porque las clases activas de otros elementos todavía están allí.

    – Ese TT

    17 de abril de 2018 a las 14:26

  • ¿Puedes actualizar la respuesta para usarla? onClick a diferencia de todo en minúsculas como lo has hecho incorrectamente

    – Peter Flanagan

    28 oct 2018 a las 18:46

También puedes hacer esto con manos.

function MyComponent (props) {
  const [isActive, setActive] = useState(false);

  const toggleClass = () => {
    setActive(!isActive);
  };

  return (
    <div 
      className={isActive ? 'your_className': null} 
      onClick={toggleClass} 
    >
      <p>{props.text}</p>
    </div>
   );
}  

avatar de usuario
Jimi Pajalá

Preferiría usar el && operador en línea if declaración. En mi opinión, proporciona una base de código más limpia de esta manera.

En general, podrías estar haciendo algo como esto:

render(){
return(
  <div>
    <button className={this.state.active && 'active'}
      onClick={ () => this.setState({active: !this.state.active}) }>Click me</button>
  </div>
)
}

Solo tenga en cuenta que las funciones de flecha son una función ES6 y recuerde configurar this.state.active valor en el constructor de la clase.

this.state = { active: false }

O si desea inyectar CSS en JSX, puede hacerlo de esta manera:

<button style={this.state.active && style.button} >button</button>

Y puedes declarar la variable json de estilo:

const style = { button: { background:'red' } }

Recuerde usar camelCase en hojas de estilo JSX.

avatar de usuario
Bane Bojanić

Bueno, su addActiveClass necesita saber en qué se hizo clic. Algo como esto podría funcionar (tenga en cuenta que agregué la información sobre qué divs están activos como una matriz de estado, y que onClick ahora pasa la información en la que se hizo clic como un parámetro después de lo cual el estado se actualiza en consecuencia; ciertamente hay formas más inteligentes de hazlo, pero entiendes la idea).

class Test extends Component(){

  constructor(props) {
    super(props);
    this.state = {activeClasses: [false, false, false]};
    this.addActiveClass= this.addActiveClass.bind(this);
  }

  addActiveClass(index) {
    const activeClasses = [...this.state.activeClasses.slice(0, index), !this.state.activeClasses[index], this.state.activeClasses.slice(index + 1)].flat();
    this.setState({activeClasses});
  }

  render() {
    const activeClasses = this.state.activeClasses.slice();
    return (
      <div>
        <div className={activeClasses[0]? "active" : "inactive"} onClick={() => this.addActiveClass(0)}>
          <p>0</p>
        </div>
        <div className={activeClasses[1]? "active" : "inactive"} onClick={() => this.addActiveClass(1)}>
          <p>1</p>
        </div>
          <div  onClick={() => this.addActiveClass(2)}>
          <p>2</p>
        </div>
      </div>
    );
  }
}

avatar de usuario
dhorelik

React tiene un concepto de estado de componentes, por lo que si desea cambiarlo, haga un setState:

constructor(props) {
  super(props);

  this.addActiveClass= this.addActiveClass.bind(this);
  this.state = {
    isActive: false
  }
}

addActiveClass() {
  this.setState({
    isActive: true
  })
}

En su uso de componentes this.state.isActive para hacer lo que necesitas.

Esto se vuelve más complicado cuando desea establecer el estado en el componente n. ° 1 y usarlo en el componente n. ° 2. Simplemente profundice más en el flujo de datos unidireccional de reacción y posiblemente redux que lo ayudará a manejarlo.

  • entiendo state pero esto todavía no explica realmente cómo actualizar el nombre de clase cuando se hace clic en un elemento

    – Peter Flanagan

    06/03/2017 a las 16:35

  • en su marcado jsx hacer – <div className={this.state.isActive ? 'active' : ''}>. Se trata de representación condicional, pero aún depende del estado.

    – dhorelik

    6 de marzo de 2017 a las 16:38


  • pero eso agregará la clase activa a cada elemento al hacer clic. Solo quiero que se haga clic en el elemento para tener el active nombre de la clase

    – Peter Flanagan

    6 de marzo de 2017 a las 16:41

  • ¿Por qué cada elemento? Agregará la clase al elemento para el que agrega la condición. Idealmente, sus artículos deben abstraerse al Item componente. Luego lo incluirá 3 veces y básicamente tendrá 3 elementos, cada uno con su propio isActive estado. ¿Es lo que quieres decir?

    – dhorelik

    6 de marzo de 2017 a las 16:47

  • sin dividirlo en un Item componente hay una manera de hacer esto?

    – Peter Flanagan

    6 de marzo de 2017 a las 16:51

avatar de usuario
Rizwan

usando React puedes agregar una clase de alternancia a cualquier id/elemento, prueba

estilo.css

.hide-text{
    display: none !important;
    /* transition: 2s all ease-in 0.9s; */
  }
.left-menu-main-link{
    transition: all ease-in 0.4s;
}
.leftbar-open{
    width: 240px;
    min-width: 240px;
    /* transition: all ease-in 0.4s; */
}
.leftbar-close{
    width: 88px;
    min-width:88px;
    transition: all ease-in 0.4s;
}

nombreDeArchivo.js

......
    ToggleMenu=()=>{
             this.setState({
                isActive: !this.state.isActive
              })
              console.log(this.state.isActive)
        }
        render() {
            return (
                <div className={this.state.isActive===true ? "left-panel leftbar-open" : "left-panel leftbar-close"} id="leftPanel">
                    <div className="top-logo-container"  onClick={this.ToggleMenu}>
                            <span className={this.state.isActive===true ? "left-menu-main-link hide-from-menu" : "hide-text"}>Welcome!</span>
                    </div>

                    <div className="welcome-member">
                        <span className={this.state.isActive===true ? "left-menu-main-link hide-from-menu" : "hide-text"}>Welcome<br/>SDO Rizwan</span>
                    </div>
    )
    }
......

  • entiendo state pero esto todavía no explica realmente cómo actualizar el nombre de clase cuando se hace clic en un elemento

    – Peter Flanagan

    06/03/2017 a las 16:35

  • en su marcado jsx hacer – <div className={this.state.isActive ? 'active' : ''}>. Se trata de representación condicional, pero aún depende del estado.

    – dhorelik

    6 de marzo de 2017 a las 16:38


  • pero eso agregará la clase activa a cada elemento al hacer clic. Solo quiero que se haga clic en el elemento para tener el active nombre de la clase

    – Peter Flanagan

    6 de marzo de 2017 a las 16:41

  • ¿Por qué cada elemento? Agregará la clase al elemento para el que agrega la condición. Idealmente, sus artículos deben abstraerse al Item componente. Luego lo incluirá 3 veces y básicamente tendrá 3 elementos, cada uno con su propio isActive estado. ¿Es lo que quieres decir?

    – dhorelik

    6 de marzo de 2017 a las 16:47

  • sin dividirlo en un Item componente hay una manera de hacer esto?

    – Peter Flanagan

    6 de marzo de 2017 a las 16:51

avatar de usuario
KadoBOT

Las respuestas anteriores funcionarán, pero en caso de que desee un enfoque diferente, intente classname: https://github.com/JedWatson/nombres de clase

¿Ha sido útil esta solución?