Solo una nota, esta pregunta NO es un problema de actualización asincrónica (al menos, no creo que lo sea).
Tengo un componente de clase con el siguiente contenido (muy simplificado para ir directo al problema):
constructor(props) { super(props); this.state = { aSelected: false; bSelected: false } } handleCheckboxChange = (e) => { const { checked, value } = e.target; console.log( 'checked: ', checked ); if(value=="a") { this.setState( {aSelected: checked}, () => { console.log('aSelected: ', this.state.aSelected); console.log("---") }); } if(value=="b") { this.setState( {bSelected: checked}, () => { console.log('bSelected: ', this.state.bSelected); console.log("---") }); } }En algún lugar dentro del retorno de representación, tengo esto:
<input> type="checkbox" value="a" onChange={this.handleCheckboxChange} checked={this.state.aSelected} disabled={ (this.state.aSelected || (!this.state.aSelected && !this.state.bSelected) ) ? false : true} </input> <input> type="checkbox" value="b" onChange={this.handleCheckboxChange} checked={this.state.bSelected} disabled={ (this.state.bSelected || (!this.state.aSelected && !this.state.bSelected) ) ? false : true} </input>Aquí está el resultado registrado en Chrome Developer Tools. Como puede ver, "marcado" se alterna adecuadamente cada vez que seleccioné y deseleccioné la casilla de verificación. Sin embargo, el estado de "seleccionado" (debería decir "aSeleccionado") nunca cambia y siempre tiene el valor de estado inicial falso. ¿Alguien sabe por qué el valor de "seleccionado" (debería decir "aSelected") nunca cambia?
Editar: mi objetivo es crear dos elementos de casilla de verificación, donde el usuario solo puede seleccionar UNO o seleccionar NINGUNO. Mientras uno está seleccionado, el otro debe estar deshabilitado .
Cuando llama a setState para actualizar el estado, React vuelve a representar el componente, lo que restablece la casilla de verificación a su estado predeterminado (es decir, sin marcar).
También deberá usar el estado actual para administrar la casilla de verificación. El JSX debería verse algo como:
<input type="checkbox" checked={this.state.aSelected} onChange={this.handleCheckboxChange} />En términos de React, esto es lo que se conoce como un "componente controlado" porque React es completamente responsable de mantenerse al día con el estado de la entrada. Lea más en los documentos aquí: https://reactjs.org/docs/forms.html#control-components vs https://reactjs.org/docs/uncontrol-components.html
Edite para que coincida con las ediciones de la pregunta : en su función de representación, asegúrese de estar usando this.state.aSlected . Tenga en cuenta que también necesita el atributochecked checked={this.state.aChecked} , de lo contrario, la casilla de verificación se desmarcará en el próximo procesamiento. Me gusta:
<input type="checkbox" value="a" onChange={this.handleCheckboxChange} checked={this.state.aSelected} // added for clarification * disabled={this.state.aSelected || (!this.state.aSelected && !this.state.bSelected) ? false : true} />Editar con un ejemplo de trabajo Aquí hay un ejemplo de CodeSandbox de trabajo donde marcar una casilla de verificación desactiva la otra:
class CheckboxComponent extends React.Component { constructor(props) { super(props); this.state = { aSelected: false, bSelected: false }; } handleCheckbox = (event) => { if (event.target.name === "boxA") { this.setState({ aSelected: event.target.checked }); } else if (event.target.name === "boxB") { this.setState({ bSelected: event.target.checked }); } }; render() { let aDisabled = this.state.bSelected && !this.state.aSelected; let bDisabled = this.state.aSelected && !this.state.bSelected; return ( <div> <label> <input type="checkbox" name="boxA" checked={this.state.aSelected} onChange={this.handleCheckbox} disabled={aDisabled} /> Checkbox A </label> <br /> <br /> <label> <input type="checkbox" name="boxB" checked={this.state.bSelected} onChange={this.handleCheckbox} disabled={bDisabled} /> Checkbox B </label> </div> ); } }