Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

WARNING: Cannot update during an existing state transition... Dúvida.

Olá pessoal, tentei replicar a deleção de notas do professor, mas na minha primeira tentativa deu o seguinte erro:

index.js:1 Warning: Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state.
    at CardNota (http://localhost:3000/static/js/main.chunk.js:533:1)
    at li
    at ul
    at ListaDeNotas (http://localhost:3000/static/js/main.chunk.js:1219:1)
    at section
    at App (http://localhost:3000/static/js/main.chunk.js:194:5)

Código fonte do erro:

import React, { Component } from "react";
import "./estilo.css";
import {ReactComponent as DeleteSvg} from "../../assets/delete.svg"

class CardNota extends Component {

  render() {
    return (
      <section className="card-nota">
        <header className="card-nota_cabecalho">
          <h3 className="card-nota_titulo">{this.props.titulo}</h3>
          <DeleteSvg onClick={this.props.apagarNota(this.props.index).bind(this)}/>
        </header>
        <p className="card-nota_texto">{this.props.texto}</p>
      </section>
    );
  }
}

export default CardNota;

Vi no vídeo que o professor não fez como eu na passagem do método onclick (eu sabia que ia ficar gambiarra, mas queria ver se funcionava assim, pois achei que o professor só não fez assim por boas práticas. Mas aí eu corrigi mais ou menos como o professor, colocando uma função apagar na classe cardNota e funcionou. Código funcionando:

import React, { Component } from "react";
import "./estilo.css";
import {ReactComponent as DeleteSvg} from "../../assets/delete.svg"

class CardNota extends Component {

//FUNÇÃO ADICIONADA
  apagar(){
    const index = this.props.index;
    this.props.apagarNota(index);
  }

  render() {
    return (
      <section className="card-nota">
        <header className="card-nota_cabecalho">
          <h3 className="card-nota_titulo">{this.props.titulo}</h3>
          <DeleteSvg onClick={this.apagar.bind(this)}/>
        </header>
        <p className="card-nota_texto">{this.props.texto}</p>
      </section>
    );
  }
}

export default CardNota;

Mas mesmo resolvendo isso me deixou inquieto, pois não consigo entender o motivo do erro. O compilador não detecta boas práticas (eu acho...) então o erro está por algum motivo técnico (se essa é a palavra). Então a questão é: Porque deu erro? Saber corrigir o erro e não entender o erro me deixa preocupado em acabar repetindo o mesmo erro em contexto diferente!!! Me ajudem aí pessoal!!!

3 respostas

Acho que matei essa charada... Investigando e tentando ler o erro (que aparente é autoexplicativo, mas programadores profissionais... me deem um desconto, eu iniciante rsrs). Então para quem tiver o mesmo problema é o seguinte (eu acho):

Qualquer método que de alguma forma vai executar uma nova rendenização e estiver dentro de um método render(), como o método do evento onClick, não pode possuir parâmetros.

Por que? Não sei... Ainda preciso de ajuda nisso. Mas imagino que esteja dando alguma espécie de erro circular um render com um método em processo que chama um render que vai chama-lo... algo assim. Então ainda fica pergunta do porque.

solução!

Oi, Jefferson, tudo bem?

Você está disparando uma forma de atualização de estado React diretamente dentro de um método render(). Sempre que o estado de um componente react é atualizado, o componente é novamente renderizado ao DOM. O que acontece na sua primeira forma de solução é que você chama this.props.apagarNota dentro da renderização. Isso significa que você está tentando atualizar o estado na renderização e que novamente, irá chamar o this.props.apagarNota(this.props.index) criando, assim, um loop infinito como você observou. O erro está informando que você está tentando atualizar o estado como consequência da atualização do estado em primeiro lugar.

Se ficou alguma dúvida é só falar!

É foi mais ou menos isso mesmo que imaginei, mas não estava tão claro. Agora está. Valeu Laís.