es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo puedo esperar una función pesada en el método de un componente de React mientras se muestra un spinner?

Quiero mostrar el mensaje “calculando…” durante un cálculo síncrono intenso en el método del Componente React. Aquí está mi código. Pero no funciona. Quiero que React llame a render() después del primer setState y del segundo setState. Pero React sólo lo llama después del segundo setState. ¿Cómo puedo cambiar adecuadamente this.state.calculating?

// nota: esto no es una función asíncrona
function myHeavyFunc() {…}

class Foo extiende React.Component {
constructor(props) {
super(props);
this.state = {calculating: false}
this.handleXX = this.handleXX.bind(this);
}

handleXX() {
this.setState({calculating: true}, () => { // primer setState
new Promise((resolve, reject) => {
const x = myHeavyFunc();
resolve(x);
}).then(x => {
this.setState({calculating: false}); // segundo setState
});
});
}

render() {
const y = this.state.calculating?

calculando…

”;
return (

{y}
);

}
}

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para cambiar correctamente this.state.calculating durante un cálculo síncrono pesado en el método del Componente React, puede probar el siguiente enfoque:

    function myHeavyFunc() {...}
    
    class Foo extends React.Components {
      constructor(props) {
        super(props);
        this.state = {calculating: false}
        this.handleXX = this.handleXX.bind(this);
      }
    
      handleXX() {
        this.setState({calculating: true}, () => { // primer setState
           const x = myHeavyFunc();
           this.setState({calculating: false}); // segundo setState
        });
      }
    
      render() {
        const y = this.state.calculating? <p>calculando...</p> : '';
        return (
          <div>
            {y}
            <button onclick="{this.handleXX}">iniciar cálculo</button>
          </div>
        );
      }
    }
    

    En este enfoque, puede eliminar el bloque Promise y then, y simplemente realizar el cálculo pesado dentro del callback del primer setState. Luego, actualice el estado nuevamente en el callback del segundo setState para cambiar this.state.calculating de vuelta a false. Esto debería hacer que se llame a render dos veces como se desea, una vez cuando calculating cambia a true, y nuevamente cuando cambia de vuelta a false.

    También tenga en cuenta que en el método render, puede usar simplemente una cadena vacía como valor false del operador ternario, en lugar de una entidad HTML.

Comments are closed.