1

I`m having a problem in understanding why in a Class based component vs Functional component the same steps yield a different result. Below I have an example that presents this difference.

   class Test extends Component {
      handleSubmit = e => {
        e.preventDefault();
        this.props.form.validateFields(async (err, values) => {
 
            await this.props.saveUserDetailsAction(values);

            const { error } = this.props; // expected modified prop 

            if (!error.status) {
              this.props.router.push("/route");
            } 
        });
      };
    }

const mapStateToProps = ({ app }) => ({
 error: app.error
});

const mapDispatchToProps = {
  saveUserDetailsAction,
};

export default compose(
  withRouter,
  connect(
    mapStateToProps,
    mapDispatchToProps
  )
)(Test);

The current error prop inside the class component reflects the changes in the redux store after the async function saveUserDetailsAction has completed, in this case dispatching an action if the request fails.

Accessing the error props after the saveUserDetailsAction function shows the updated prop.

The same code written as a functional component does not yield the same result. Accessing the error prop after the saveUserDetailsAction function completed doesn't reflect the change in the store yet.

  const Test = (props) => {
      const handleSubmit = e => {
        e.preventDefault();
        props.form.validateFields(async (err, values) => {     

            await props.saveUserDetailsAction(values);

            const { error } = props;  // unchanged prop when accessed here

            if (!error.status) {
              props.router.push("/route");
            }
        });
      };
    }

const mapStateToProps = ({ app }) => ({
 error: app.error
});

const mapDispatchToProps = {
  saveUserDetailsAction,
};

export default compose(
  withRouter,
  connect(
    mapStateToProps,
    mapDispatchToProps
  )
)(Test);
Mihai
  • 11
  • 1

1 Answers1

0

To my point of view, it's an anti-pattern, you need to wait for another cycle to get the correct error props. Functional component is the right behavior. What you need to do is find a way to return error here :

const { error } = await props.saveUserDetailsAction(values);

Redux store error variable can still be used in another component

Other way to do it is to use a useEffect(() => {}, [error]) and to distinguish 3 states "No Submitted Yet", "Submitted without error", "Submitted with error" but i don't recommend it