Tengo un formulario con type="range"
. Ahora me gustaría agregar 3 botones que cambien el mismo valor que hace el formulario. Por alguna razón, el evento onClick de los botones parece llamarse repetidamente al llamar a la función de renderizado.
Este es mi componente:
class Slider extends Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.handleButton = this.handleButton.bind(this); } handleChange() { this.props.onSetCountdown(parseInt(this.refs.seconds.value, 10)); } handleButton(value) { this.props.onSetCountdown(parseInt(value, 10)); } render() { return( <div> <form className={styles.ttSlider} ref="form"> <input max="480" min="60" name="slider" onChange={this.handleChange} ref="seconds" type="range" value={this.props.totalSeconds}/> <button onClick={this.handleButton(60)}>1min</button> <button onClick={this.handleButton(180)}>3min</button> <button onClick={this.handleButton(300)}>5min</button> </form> </div> ) } } Slider.propTypes = { totalSeconds: React.PropTypes.number.isRequired, onSetCountdown: React.PropTypes.func.isRequired };
Y esto es del componente padre:
handleSetCountdown(seconds) { this.setState({ count: seconds }); }
Desde el renderizado del componente principal:
<Slider totalSeconds={count} onSetCountdown={this.handleSetCountdown}/>
Este es el error que me sale:
Advertencia: setState(...): No se puede actualizar durante una transición de estado existente (como dentro del
render
o el constructor de otro componente). Los métodos de renderizado deben ser una función pura de accesorios y estado; Los efectos secundarios del constructor son un antipatrón, pero se pueden mover acomponentWillMount
.
Para mí, esto parece que se llama a los botones onClick mientras el componente aún se está procesando. ¿Qué estoy haciendo mal?
Es porque en lugar de pasar la función al evento onClick, estás llamando a la función directamente.
Intenta hacerlo de esta manera:
<button onClick={() => { this.handleButton(60)}}>1min</button> <button onClick={() => { this.handleButton(180)}}>3min</button> <button onClick={() => { this.handleButton(300)}}>5min</button>
Encontré la respuesta aquí: la función React onClick se activa al renderizar
¡Espero eso ayude!
Si no desea utilizar funciones anónimas por ningún motivo, el segundo método es utilizar bind directamente en la función de representación. Luego puede eliminar líneas en su constructor :)
<button onClick={this.handleButton.bind(this, 60)}>1min</button>