Author avatar

Gaurav Singhal

Implement Conditional Action on State in React-redux

Gaurav Singhal

  • Oct 21, 2020
  • 5 Min read
  • 165 Views
  • Oct 21, 2020
  • 5 Min read
  • 165 Views
Web Development
Front End Web Development
Client-side Frameworks
React

Introduction

When working with enterprise-level React apps, you have to deal with complex state management. The complexity of the state increases as the app scales. You can avoid problems related to the state in such apps by using a state management library. A state management library does all the heavy lifting for you and provides you with a declarative API to manage state in the whole app.

Redux is a popular state management library for React. Redux helps you manage the state with predictable behavior, which helps with long-term code maintainability. In this guide, you will learn how to use Redux to dispatch actions conditionally based on the value in the current global store.

Understanding Actions

Actions are plain objects that send data or payloads of information from your component to the global store object. Below is an example action object that represents an action for authenticating a user.

1
const AUTHENTICATE = `LOGIN_USER`;
js
1
2
3
4
5
6
7
{
    type: AUTHENTICATE,
    payload: {
        email: '[email protected]',
        password: 'john123'
    }
}
js

The type key is the only mandatory property for action; other properties are up to you and can be flexible to meet your app requirements. It's a good practice to send as little data in each action as possible and avoid nested objects.

Dispatching Action from Component

Now that you understand of Redux actions, in this section, you will learn how to dispatch an action from a component.

As an example, consider a LoginForm component that handles the form validation and submission; once the form is successfully submitted, it passes the values to the parent component, i.e., the LoginPage component using the onSubmit prop. When the form submits, you need to dispatch the AUTHENTICATE action, which will take care of the authentication process.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import React from "react";

class LoginPage extends React.Component {
  constructor(props) {
    super(props);

    this.handleFormSubmit = this.handleFormSubmit.bind(this);
  }

  handleFormSubmit(values) {
    // dispatch AUTHENTICATE action
  }

  render() {
    return (
      <div>
        <LoginForm onSubmit={this.handleFormSubmit} />
      </div>
    );
  }
}

export default LoginPage;
jsx

Now to dispatch the action from the LoginPage component, you need to use the connect method from the react-redux library.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import React from "react";
import { connect } from "react-redux";

class LoginPage extends React.Component {
  constructor(props) {
    // ...
  }

  handleFormSubmit(values) {
    // dispatch AUTHENTICATE action
    this.props.dispatch({
      type: AUTHENTICATE,
      payload: values,
    });
  }

  render() {
    // ...
  }
}

export default connect()(LoginPage);
jsx

The connect method is an enhancer function that connects the component with the global store and also injects a dispatch method in the prop.

The dispatch method takes the action object as its parameter and dispatches that action to the Redux store.

Dispatching Action Conditionally from Component

Consider that the authentication is already in progress, in which case you do not want to dispatch the AUTHENTICATE action. So here, you need to connect the component to the global store and retrieve the authentication status. You can do that by passing the mapStateToProps argument to the connect() method.

1
2
3
4
5
6
const mapStateToProps = (globalState) => {
  const { isAuthenticating } = globalState;
  return { isAuthenticating };
};

export default connect(mapStateToProps)(LoginPage);
jsx

Then in the handleFormSubmit method, you can do as follows.

1
2
3
4
5
6
7
handleFormSubmit(values) {
    if (!this.props.isAuthenticating)
      this.props.dispatch({
        type: AUTHENTICATE,
        payload: values,
      });
}
js

The above condition will ensure that the AUTHENTICATE action is dispatched only when the isAuthentication state is set to false.

Here is the complete code for your reference.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import React from "react";
import { connect } from "react-redux";

class LoginPage extends React.Component {
  constructor(props) {
    super(props);

    this.handleFormSubmit = this.handleFormSubmit.bind(this);
  }

  handleFormSubmit(values) {
    if (!this.props.isAuthenticating)
      this.props.dispatch({
        type: AUTHENTICATE,
        payload: values,
      });
  }

  render() {
    return (
      <div>
        <LoginForm onSubmit={this.handleFormSubmit} />
      </div>
    );
  }
}

const mapStateToProps = (globalState) => {
  const { isAuthenticating } = globalState;
  return { isAuthenticating };
};

export default connect(mapStateToProps)(LoginPage);
jsx

Conclusion

Redux makes it easier for you to predict the app state and the flow of data. Redux dev-tools provides you with "time-travel" debugging that lets you dispatch any past actions.

There's still a lot of ground to cover in state management with Redux. You can start by looking at the Redux docs, which are very concise and beginner-friendly.

1