Esto me ha pasado algunas veces. Siempre me las he arreglado para solucionar el problema, pero todavía estoy intrigado por entender por qué sucede esto y qué me he perdido.
Esencialmente, si tengo una condición dentro de mi método de render
que especifica la clase para mi div
:
let divClass = this.state.renderCondition ? 'red' : 'blue';
De forma predeterminada, configuro renderCondition
dentro de mi estado en falso.
Si luego defino un controlador onClick
en un botón (como se muestra a continuación) y hago clic en el botón, mientras se llama al renderizado, el DOM NO se actualiza. Es decir, la clase no cambia.
onClickCompile: function() { this.setState({renderCondition: true}, function() { synchronousSlowFunction(); }); }
Esto parece tener algo que ver con la ejecución de código sincrónico lento en el sentido de que si el código es rápido y simple, el DOM SE actualiza adecuadamente.
Si envuelvo la llamada a synchronousSlowFunction
en un tiempo de espera de 500 milisegundos, todo funciona como se esperaba. Sin embargo, me gustaría entender lo que he entendido mal, de modo que no necesito este truco.
¿Puedes compartir el código del botón onClick? Puede que me equivoque, pero esto parece un botón configurado incorrectamente en el oyente de clics.
Asegúrese de que la devolución de llamada onClick esté definida sin (), es decir
<button onClick={this.something} />
en vez de:
<button onClick={this.something()} />
Publique más código para que podamos obtener una imagen mejor (más grande)
synchronousSlowFunction es, como mencionaste, sincrónico. Esto significa que bloquea su componente mientras se está ejecutando. Eso significa que reaccionar no puede actualizar su componente, porque tiene que esperar a que se complete la función de devolución de llamada hasta que pueda llamar a renderizar con los valores actualizados. El ajuste setTimeout hace que la llamada sea asíncrona, de modo que la reacción pueda procesar/actualizar su componente, mientras la función está haciendo su trabajo. No es el retraso de tiempo lo que hace que funcione, sino simplemente la devolución de llamada, que no bloquea el procesamiento. También puede envolverse en una Promesa o hacer que la función lenta sea asíncrona para evitar el bloqueo del renderizado.
Prueba algo como esto:
this.setState((state) => ({ ...state, renderCondition: true }));
Tal vez esté haciendo otro setState para renderCondition en algún lugar donde el código anterior debería solucionar tales cosas.
o tal vez intente usar PureComponent
import React, { PureComponent } from 'react' export default class TablePreferencesModal extends PureComponent { render() { return ( <div> </div> ) } }