react estado entre comunicacion componentes javascript html reactjs event-handling

javascript - estado - react comunicacion entre componentes



¿Por qué llamar al método setState no muta el estado inmediatamente? (3)

Ok, intentaré hacerlo rápido porque DEBERÍA ser una solución fácil ...

He leído un montón de preguntas similares, y la respuesta parece ser bastante obvia. ¡Nada que tendría que buscar en primer lugar! Pero ... estoy teniendo un error que no puedo entender cómo solucionarlo o por qué está sucediendo.

Como sigue:

class NightlifeTypes extends Component { constructor(props) { super(props); this.state = { barClubLounge: false, seeTheTown: true, eventsEntertainment: true, familyFriendlyOnly: false } this.handleOnChange = this.handleOnChange.bind(this); } handleOnChange = (event) => { if(event.target.className == "barClubLounge") { this.setState({barClubLounge: event.target.checked}); console.log(event.target.checked) console.log(this.state.barClubLounge) } } render() { return ( <input className="barClubLounge" type=''checkbox'' onChange={this.handleOnChange} checked={this.state.barClubLounge}/> ) }

Más código rodea esto, pero aquí es donde radica mi problema. Debería funcionar, ¿verdad?

También he intentado esto:

handleOnChange = (event) => { if(event.target.className == "barClubLounge") { this.setState({barClubLounge: !this.state.barClubLounge}); console.log(event.target.checked) console.log(this.state.barClubLounge) }

Entonces tengo esos dos console.log() , ambos deberían ser lo mismo. ¡Literalmente estoy configurando el estado para que sea el mismo que el event.target.checked en la línea por encima de él!

Pero siempre devuelve lo contrario de lo que debería.

Lo mismo ocurre cuando uso !this.state.barClubLounge ; ¡Si comienza falso, en mi primer clic sigue siendo falso, incluso si la casilla de verificación está marcada o no se basa en el estado!

Es una paradoja loca y no tengo idea de lo que está pasando, ¡por favor ayuda!


Dado que setState es una función asíncrona. Eso significa que después de llamar a setState, la variable de estado no cambia inmediatamente. Entonces, si desea realizar otras acciones inmediatamente después de cambiar el estado, debe usar el método de devolución de llamada de setstate dentro de su función de actualización setState.

handleOnChange = (event) => { let inputState = event.target.checked; if(event.target.className == "barClubLounge") { this.setState({ barClubLounge: inputState}, () => { //here console.log(this.state.barClubLounge); //here you can call other functions which use this state variable // }); } }


Esto es por diseño debido a consideraciones de rendimiento. setState en React es una función garantizada para volver a representar Component, que es un proceso costoso de la CPU. Como tal, sus diseñadores querían optimizar mediante la recopilación de múltiples acciones de representación en una, por lo tanto, setState es asíncrono.


La razón es que setState es asíncrono , no puede esperar el valor de state actualizado justo después de setState , si desea verificar el valor use un método de callback . Pase un método como devolución de llamada que se ejecutará después de que setState complete su tarea.

¿Por qué setState es asíncrono?

Esto se debe a que setState altera el state y provoca que se vuelva a setState . Esta puede ser una operación costosa y hacerla synchronous puede dejar al navegador sin respuesta. Por lo tanto, las llamadas a setState son asynchronous están setState para una mejor experiencia y rendimiento de la interfaz de usuario.

De Doc :

setState () no muta inmediatamente this.state pero crea una transición de estado pendiente. Acceder a this.state después de llamar a este método puede devolver el valor existente. No hay garantía de operación síncrona de llamadas a setState y las llamadas pueden ser agrupadas para obtener ganancias de rendimiento.

Usando el método de devolución de llamada con setState:

Para verificar el valor de state actualizado justo después de setState , use un método de devolución de llamada como este:

setState({ key: value }, () => { console.log(''updated state value'', this.state.key) })

Mira esto:

class NightlifeTypes extends React.Component { constructor(props) { super(props); this.state = { barClubLounge: false, seeTheTown: true, eventsEntertainment: true, familyFriendlyOnly: false } } handleOnChange = (event) => { // Arrow function binds `this` let value = event.target.checked; if(event.target.className == "barClubLounge") { this.setState({ barClubLounge: value}, () => { //here console.log(value); console.log(this.state.barClubLounge); //both will print same value }); } } render() { return ( <input className="barClubLounge" type=''checkbox'' onChange={this.handleOnChange} checked={this.state.barClubLounge}/> ) } } ReactDOM.render(<NightlifeTypes/>, document.getElementById(''app''))

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id=''app''/>