React to async/await

in #development7 years ago (edited)

React to async/await


I got curious this past weekend about javascript’s ES7 async/await. After reading a couple of blog posts I got the basic idea of how it works and why it’s gotten so much chatter. Long story short, it helps you limit the side effects of using promises aka .then. After learning this new bad body technique, I thought to myself… how can I apply it in my react applications? There’s are plenty of blog posts with detailed explanation of what it is and how it would be used in plain old vanilla Javascript. My goal for today is to use the techniques I learned in my react/redux application specifically on a actions and component. For the examples below, I will show I would normally approach each problem using Promises followed by the async await method.

Actions

In this example, this is how I would typically approach creating a new user via promises.Promise approach

export default function createUser(params) {
  const request = axios.post('http://www..., params);

  return (dispatch) => request
    function onSuccess(success) {
      dispatch({ type: CREATE_USER, payload: success });
      return success;
    }
   function onError(error) {
      dispatch({ type: ERROR_GENERATED, error });
      return error;
    }
   .then(success => onSuccess, error => onError);
}

Besides some nice helper functions onSuccess and onError , everything is pretty standard. With promises, I get the response from my API request and store the result to my appropriate functions via success and error. How would I go about writing it via async/await ?async/await approach

export default function createUser(params) {  
  return async dispatch => {
    function onSuccess(success) {
      dispatch({ type: CREATE_USER, payload: success });
      return success;
    }
   function onError(error) {
      dispatch({ type: ERROR_GENERATED, error });
      return error;
    }
   try {
      const success = await axios.post('http://www..., params);
      return onSuccess(success);
    } catch (error) {
      return onError(error);
    }
  }
}

I added the async prior to the dispatch andawait in front of axios.post . This method is the exact patten we need to follow to use async/await . The beauty of this approach is that it allows asynchronous code to look more synchronous. No more need for a .then callback! We just attach the response from the API request we make into the success variable and dispatch the proper actions!

Components

Now that we created an appropriate createUser action function. How can we use this on our component level? Like before, I’ll show the promise approach followed by the async/await.Promise approach

import React, { Component } from 'react';
import { connect } from 'react-redux'
import createUser from 'path of createUser'
class userForm extends Component {
  constructor(props) {
    super(props);
    this.onSubmit = this.onSubmit.bind(this);
  }
 onSubmit(e) {
    e.preventDefault();
   let formInput = this.refs.createUserForm;
    this.props.createUser(formInput.value)
      .then((response) => {
        // Do something with the response... add more thens.. etc
      }, (error) => {
        // Do something with the error
      });
   }
 render() {
    return (
      <form onSubmit={this.onSubmit}>
        <input placeholder="current user" ref="createUserForm" />
        <button>Submit</button>
      </form>
    );
  }
}
export default connect(null, {
  createUser
})(userForm)

After a form is submitted via click and this.props.createUser,we are returned a promise. With that promise value we can do a variety of things such as add more component state functionality, add more promise functions, etc. Lets see how we can do it using the async/await method.async/await approach

import React, { Component } from 'react';
import { connect } from 'react-redux'
import createUser from 'path of createUser'
class userForm extends Component {
  constructor(props) {
    super(props);
    this.onSubmit = this.onSubmit.bind(this);
  }
 async onSubmit(e) {
    e.preventDefault();
  
    let formInput = this.refs.createUserForm;
    try {
      const response = await this.props.createUser(formInput.value);
      // do something with response
    } catch(error) {
      // do something with error
    }
  }
 render() {
    return (
      <form onSubmit={this.onSubmit}>
        <input placeholder="current user" ref="createUserForm" />
        <button>Submit</button>
      </form>
    );
  }
}
export default connect(null, {
  createUser
})(userForm)

Like our action functions, the async/await approach in our components allows our asynchronous code to look synchronous. We define the result from the this.props.createUser in response , instead of using then like we do in promises.

Conclusion
For simple use cases like the example, there aren’t as many nuisances between using promises vs. async/await. However, the biggest gripe about using promises is the potential of adding too many .then when you need to perform multiple api requests/actions. Async/await allows our code to look synchronous which is always a plus. The code looks clean!

Next Steps
I would consider this section to be a larger portion of a 2 step blog. My next plan is to show an example of writing tests with async await. See you then!


The original article was created on medium and you can find the link here

Sort:  

excellent

Thank you :)

Congratulations @kkomaz! You have completed some achievement on Steemit and have been rewarded with new badge(s) :

You got a First Reply

Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here

If you no longer want to receive notifications, reply to this comment with the word STOP

By upvoting this notification, you can help all Steemit users. Learn how here!

Coin Marketplace

STEEM 0.19
TRX 0.12
JST 0.027
BTC 64928.52
ETH 3525.30
USDT 1.00
SBD 2.36