Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React dispatch a method in async call

How to dispatch the redux function in react async call. When I call the dispatch function dispatch(updatingcontact(), I'm getting error that dispatch is not defined.

const UpdateContact = async (URL, method, type, address) => {
dispatch(updatingcontact()
const APIResponse = await fetch(URL, {
    method: POST,
    headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
    },
    body: JSON.stringify({
        "webContacts": {
            "address": address
        }
    })
})
    .then(response => {
        if (!response.ok) {
            return Promise.reject(response.statusText);
        }
        return response.json();
    })
    .then(status => {
        return status
    })
    .catch(error => {
        console.log(error);
    });
}

I just want to call the updatingcontact() function inside the UpdateContact and call the reducer to display the updating message in UI.

function updatingcontact() {
return {
    type: ACTIONTYPES.UPDATING_CONTACT
 }
}
like image 740
Maria Jeysingh Anbu Avatar asked Mar 20 '20 14:03

Maria Jeysingh Anbu


1 Answers

You need to use some async middleware like redux-thunk to make asynchronous API calls. Using redux's higher order function connect will connect your React component to the redux store.

Your thunk would look something like this:

Note that Redux will pass dispatch argument to the thunk function for dispatching actions.

export const updatingContact = (url, address) => {
  return async (dispatch) => { 
    dispatch({ type: ACTIONTYPES.UPDATING_CONTACT_STARTS }) // for showing spinner or loading state in your component

    try {
      const response = axios.post(url, {
        headers: {
          "Content-Type": "application/json",
          "Accept": "application/json"
        },

        body: JSON.stringify({
          webContacts: {
            address: address
          }
        })
      })

      dispatch({
        type: ACTIONTYPES.UPDATING_CONTACT_SUCCESS,
        data: { updatedContactList: response.data.updatedContactList }
      })
    } catch (error) {
      dispatch({
        type: ACTIONTYPES.UPDATING_CONTACT_ERROR,
        data: { error: error }
      })
    }
  }
}

After that, whatever your component needs, it's availble in the redux store. To dispatch from your UpdateContact component, you just need to do this:

import { updatingContact } from "./actions.js" 

class UpdateContact extends Component {

  componentDidMount() {
      this.props.dispatch(updatingContact()) 
  }

  render() { 
    const {address, phoneNumber } = this.props
    return (
      <div>
        Adress: {address}
        Phone No.: {phoneNumber}
      </div>
    )
  }


const mapStateToProps = () => {
  // return whatever you need from the store like contact details, address, etc
  address: state.updatingContactReducer.address,
  phoneNumber: state.updatingContactReducer.phoneNumber
}

export default connect(mapStateToProps)(UpdateContact)

Notice that if you don't provide mapDispatchToProps to connect, you will still be able to use dispatch in your component because it's available by default.

If you provide mapDispatchToProps, the way you would now dispatch from your component would be- this.props.updatingContact().

mapDispatchToProps just binds action creators with dispatch and pass these new bound functions as props to the component.

like image 105
metalHeadDev Avatar answered Oct 13 '22 17:10

metalHeadDev