TransWikia.com

¿Cómo obligar a mi componente a renderizar después del setState?

Stack Overflow en español Asked by Alex Varela on August 26, 2021

Estoy haciendo un handlechange para un componente. El código es el siguiente:

function insertData(newData) {
    return fetch(url, {
    method: 'POST',
    mode: 'cors',
    headers: {
        'Accept': 'application/json, text/plain, */*',
        'Content-Type': 'application/json'
    },
    body: JSON.stringify(newData) 
});
}

handleRowAdd = (newData) => 
              new Promise((resolve) => {
                setTimeout(() => {
                  resolve();
                    const data = this.state.data;
                    newData = insertData(newData);
                    newData.then(result => {
                        if(result.ok) {
                            return result.json()
                        }
                        throw new Error('Error al insertar valor.');
                    }).then(result => {
                        data.push(result);;
                        this.setState({data: data}, console.log(this.state.data));
                    }, error => {
                        console.log(error);
                    });
                }, 600);
              });

Este handleRowAdd, como pueden ver la idea es que inserte un dato en la BD a través de un api. La respuesta del API, es el valor que envié pero con el id de la base de datos que fue asignado y demás. Todo lo hace correcto, el problema es que al ejecutar this.setState, este no refresca mi componente, por lo que de nada me sirve devolver el valor ingresado si no puedo verlo. Buscando, encontré ese forceUpdate, pero no hace nada.

Edición:

Cambio de la función, la anterior no funcionaba por lo que la modifiqué y ahora el callback del setState, si devuelve el state modificado, pero sigue sin refrescar la pantalla. Encontré algo de location.reload(), pero quiero saber si es un error en mi lógica.

Gracias de antemano.

2 Answers

Existen varias cosillas por solucionar, pero si todo te funciona tratare de "adivinar" el lugar donde este mal tu codigo.

1.-const

La diferencia entre var,let y const si bien no son tan amplias, si que son diferentes. Y lo que hace const es muy similar a lo que realiza let con la diferencia de que los valores de const no son mutables("no pueden cambiar").

Dicho esto quizá el error estuviera en:

const data = this.state.data;

Yo lo cambiaría por:

let data = [...this.state.data];

2.- this dentro de la promesa

No estoy seguro de esta opción, pero por alguna razón this no me funcionaba dentro de las promesas. Es decir si funciona pero no es el this de la clase, sino él de la promesa.(espero se entienda)

Entonces antes de utilizar this en la promesa utilizaba _selft que es una variable que creaba antes de entrar en la promesa.

let _selft=this;
new Promise(...
    const data = _selft.state.data;
    newData = insertData(newData);
    newData.then(...).then(result => {
        _selft.setState({data: newObject});
    })

3.- Mi forma de hacer lo mismo

Veo una promesa y un setTimeout no se el motivo pero no lo incluiré en el siguiente ejemplo que es como yo realizo una petición fetch.

async subirInfo(e){
    e.preventDefault();//evita la accion de una etiqueta button, a, submit
    //validar datos
    let formData = new FormData();
    formData.append('nombre', this.state.form.nombre)
    //carga de datos
    try{
        let config = {
            method:'POST',
            header:{
                'Accept' : 'application/json',
                'Content-Type' : 'application/json'
            },
            body:formData
        }

        let res = await fetch(url,config);

        if(res.ok){//si la peticion fue exitosa retorna true
            let data = await res.json();//data es un objeto de propietario             
            this.setState({
                propietarios:this.state.propietarios.concat(data),
            })
        }else{
            console.log(error);
        }
    }catch(e){
        console.log(e);
    }
}

Donde se encuentra dos palabra reservadas como async para especificar que la funcion es asyncrona y await que es para esperar la respuesta de la promesa fetch.

Tambien se puede aplicar en funciones flecha asi:

conts subirInfo= async event => {....}
//o asi
conts subirInfo= async (e) => {....} //jajaj no cambio nada.

Espero que con alguna de las opciones soluciones tu error.

Correct answer by Shassain on August 26, 2021

  • React automaticamente renderiza cuando hay un cambio en el state, no tienes por que forzar el renderizado.
  • El state en React reconoce cuando es el mismo objeto por lo que no estás cambiando de objeto realmente

Puedes intentar esto:

   handleRowAdd = (newData) => 
          new Promise((resolve) => {
            setTimeout(() => {
              resolve();
                const data = this.state.data;
                newData = insertData(newData);
                newData.then(result => {
                    if(result.ok) {
                        return result.json()
                    }
                    throw new Error('Error al insertar valor.');
                }).then(result => {

                    //DETALLE ESTÁ AQUÍ
                    const newObject = {...data};
                    newObject.push(result);;
                    this.setState({data: newObject});

                }, error => {
                    console.log(error);
                });
            }, 600);
          });

Con esto te aseguras de cambiar el state, espero te funcione

Answered by Saul Moreyra on August 26, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP