Actualización del estado de react de Redux causando la actualización máxima en comparación con el error excedido

Soy bastante nuevo para React y Redux, y he quedado un poco atorado al mostrar el estado de error basado en una respuesta de error del servidor (utilizando express).

La mayoría de las otras cuestiones similares He investigado están relacionados con onClick, onSubmit, o onChange, pero no he visto uno como el mío.

Resultado previsto: El estado de error se recupera de la tienda y se muestra dentro del componente

La cuestión se deriva de este segmento:

if (nextProps.errors){
  this.setState({ errors: nextProps.errors });    
}

The full Login.js:

import React, { Component } from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import "../css/login.css";
import { loginUser } from "../../redux/actions/authActions";
import TextFieldGroup from "../common/textFieldGroup";

class Login extends Component {
  constructor() {
    super();
    this.state = {
      username: '',
      password: '',
      errors: {}
    };
    
    this.onChange = this.onChange.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
  }

  componentDidMount() {
    if (this.props.auth.isAuthenticated) {
      this.props.history.push('/dashboard');
    }
  }

  componentDidUpdate(nextProps) {
    if (nextProps.auth.isAuthenticated) {
      this.props.history.push('/dashboard');
    }

    if (nextProps.errors){
        this.setState({ errors: nextProps.errors });    
    }
  }

  onSubmit(e) {
    e.preventDefault();

    const userData = {
      username: this.state.username,
      password: this.state.password
    };

    this.props.loginUser(userData);
  }

  onChange(e) {
    this.setState({ [e.target.name]: e.target.value });
  }

  render() {
    const { errors } = this.state;

    return (
      

Log In

); } } Login.propTypes = { loginUser: PropTypes.func.isRequired, auth: PropTypes.object.isRequired, errors: PropTypes.object.isRequired }; const mapStateToProps = state => ({ auth: state.auth, errors: state.errors }); export default connect(mapStateToProps, { loginUser })(Login);

He intentado:

  1. Asignar el valor a una variable temp, pero esto es extremadamente clunky y hace que el código confuso en mi opinión.
  2. Validando si es nulo/no nulo, naturalmente esto reforzó el bucle infinito o validado positivamente, ya que no era nulo, por lo que el estado de error nunca actualiza en la página.

Definitivamente estoy recibiendo la respuesta correcta del error del servidor como puedo verlo en las herramientas Redux dev.

Gracias por adelantado.

Pregunta hecha hace 3 años, 4 meses, 28 días - Por codemaestro


3 Respuestas:

  • Cambiar la condición de:

    if (nextProps.errors)
    

    a:

    if (this.props.errors !== nextProps.errors)
    

    Parece estar trabajando bien por ahora. Crédito a @emile-bergeron para la solución

    Respondida el Dec 17, 2020 a las 15:12 - por geekguru

    Votos positivos: 0 | Votos negativos: 0

  • El problema que estás experimentando se debe a que estás utilizando componentDidUpdate de manera incorrecta. componentDidUpdate recibe dos parámetros: prevProps y prevState, no nextProps.

    Por lo tanto, debes modificar tu método componentDidUpdate de la siguiente manera:

    jsx
    componentDidUpdate(prevProps, prevState) {
      if (this.props.auth.isAuthenticated) {
        this.props.history.push('/dashboard');
      }
    
      if (this.props.errors !== prevProps.errors){
        this.setState({ errors: this.props.errors });    
      }
    }
    

    Al utilizar prevProps.errors en la condición, puedes comparar el estado actual de los errores con el estado anterior de los errores, y solo actualizar el estado si hay una diferencia.

    Con estos cambios, tu componente debería funcionar correctamente y mostrar los errores del servidor cuando sea necesario.

    Espero que esta solución te haya sido útil. ¡Déjame saber si necesitas más ayuda!

    Respondida el Dec 18, 2020 a las 15:10 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • El error "Actualización del estado de React causando actualización máxima en comparación con el error excedido" generalmente ocurre cuando un componente se actualiza con demasiada frecuencia, lo que resulta en un bucle infinito. En tu caso, el problema parece estar en el método componentDidUpdate del componente Login.

    Específicamente, cuando se actualiza el componente Login y nextProps.errors no es null, estás estableciendo el estado de errors a nextProps.errors. Esto hace que el componente se actualice nuevamente, ya que el estado de errors ha cambiado.

    Para resolver este problema, debes asegurarte de que solo actualices el estado si nextProps.errors es diferente del estado actual de errors. Aquí tienes cómo puedes actualizar el código:

    
    componentDidUpdate(nextProps) {
        if (nextProps.auth.isAuthenticated) {
          this.props.history.push('/dashboard');
        }
    
        if (nextProps.errors && nextProps.errors !== this.props.errors) {
            this.setState({ errors: nextProps.errors });    
        }
    }
    

    Al agregar la verificación nextProps.errors !== this.props.errors, solo actualizarás el estado de errors cuando el valor de nextProps.errors sea diferente del valor actual de errors. Esto evitará el bucle infinito y permitirá que el componente se actualice correctamente cuando se produzcan errores.

    Ten en cuenta que también puedes utilizar la función shouldComponentUpdate para controlar cuándo se actualiza el componente. En este caso, puedes utilizar shouldComponentUpdate para comparar nextProps.errors con this.props.errors y devolver false si son iguales, evitando así la actualización innecesaria del componente.

    Respondida el Dec 18, 2020 a las 15:16 - por Gemini

    Votos positivos: 0 | Votos negativos: 0