Search code examples
reactjsreact-nativeasync-awaitredux-thunk

redux-thunk and async/await actions: how to combine them all?


The following piece of code is one of my actions and actually works.

export const loadChannelList = () => { 
    return async (dispatch) => {

        dispatch ({
            type: CHANNEL_LIST_LOADING
        });

        try {
            const response  = await fetch('<my server url>');
            const responseJson = await response.json();

            dispatch ({
                type: CHANNEL_LIST_LOADING_OK,
                payload: "ok" // response.json()
            });

        } catch(error) {
            dispatch ({
                type: CHANNEL_LIST_LOADING_FAILED,
                payload: error
            });
        }
    };
}

In a component, I use this in this way:

componentWillReceiveProps(nextProps) {
        if (this.props.connectionStatus != 'ok' 
            && nextProps.connectionStatus == 'ok'
           ) {
            this.props.loadChannelList();
        }
}

I ask you: is this the right way to use async/await when playing with redux-thunk ?

I ask this because it's the first time I use async/await in a react-native app in a redux-thunk action and I'd like to be sure that I'm not doing some anti-pattern or other errors


Solution

  • You shouldn't need an await on:

    const response  = await fetch('<my server url>');
    

    It's only needed on:

    const responseJson = await response.json();
    

    This is because the fetch statement returns a Promise. So the await is only needed to await the result of the Promise.

    Here's a simplified example using some mock functions:

    // A fake asynchronous request
    function fetch(x) {
      return new Promise(resolve => {
        setTimeout(() => {
          resolve({
            data: x
          });
        }, 3000);
      });
    }
    
    // A fake Dispatch function
    function fakeDispatch(theData) {
      console.log(theData);
    }
    
    // A function to run on componentDidMount or similar
    async function getData(x) {
      const response = fetch(x);
      
      // call the Dispatch
      fakeDispatch(await response);
    }
    
    // componentDidMount
    console.log('Mounting component...');
    getData("some data");