Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling async request with React, Redux and Axios?

Tags:

I am new to React JS and Redux and it has been too overwhelming to get going. I am trying to make a POST request using Axios, but I am unable to make it. May be I am missing something in the container file. Below is the code. Check plnkr

Update: I am getting @@redux-form/SET_SUBMIT_SUCCEEDED message after submitting. But when I am checking in the network tab, I don't see the call to API. And also when I am consoling the submitted values, I see only name and fullname values. It doesn't consist of logo and details. What am I missing?

Component file

   import React, { PureComponent } from 'react'    import PropTypes from 'prop-types'    import { Field,reduxForm } from 'redux-form'    import {   Columns,Column, TextArea, Label,Button  } from 'bloomer'    import FormField from 'FormField'     const validate = (values) => {      const errors = {}     const requiredFields =        ['organizationName','organizationFullName','organizationDetails']      requiredFields.forEach((field) => {      if (!values[field]) {      errors[field] = 'This field can\'t be empty!'     }   })      return errors }    const formConfig = {    validate,    form: 'createOrganization',    enableReinitialize: true    }    export class CreateOrganization extends PureComponent {    static propTypes = {      isLoading:PropTypes.bool.isRequired,      handleSubmit: PropTypes.func.isRequired, // from react-redux           submitting: PropTypes.bool.isRequired // from react-redux     }    onSubmit = data => {      console.log(data)    }   render () {      const { handleSubmit,submitting,isLoading } = this.props       return (         <Columns isCentered>         <form onSubmit={handleSubmit(this.onSubmit.bind(this))} >             <Column isSize='3/6' >                     <Label>Organization Name</Label>                          <Field                name="organizationName"               component={FormField}               type="text"               placeholder="Organization Name"             />              </Column>                    <Column isSize='3/6'>             <Label>Organization Full Name</Label>                           <Field               name="organizationFullName"               component={FormField}               type="text"               placeholder="Organization Full Name"             />             </Column>               <Column isSize='3/6'>                         <Label>Organization Logo</Label>                           <Input                                 name="organizationLogo"                                 type="file"               placeholder="Logo"             />            </Column>            <Column isSize='3/6'>             <Label>Organization Details</Label>                          <TextArea placeholder={'Enter Details'} />                          </Column>                       <Column >             <span className="create-button">               <Button type="submit" isLoading={submitting || isLoading} isColor='primary'>                 Submit               </Button>               </span>                <Button type="button" isColor='danger'>                 Cancel               </Button>                           </Column>            </form>       </Columns>     )       } }    export default reduxForm(formConfig)(CreateOrganization) 

Container File

   import React, { PureComponent } from 'react'    import PropTypes from 'prop-types'    import { connect } from 'react-redux'    import Loader from 'Loader'    import organization from 'state/organization'    import CreateOrganization from '../components/createOrganization'     export class Create extends PureComponent {    static propTypes = {          error: PropTypes.object,      isLoaded: PropTypes.bool.isRequired,        create: PropTypes.func.isRequired,        }     onSubmit = data => {       this.props.create(data)     }      render () {       const { isLoaded, error } = this.props     return (              <CreateOrganization onSubmitForm={this.onSubmit} isLoading=          {isLoading} />          )    }  }     const mapStateToProps = state => ({      error: organization.selectors.getError(state),      isLoading: organization.selectors.isLoading(state)    })      const mapDispatchToProps = {       create: organization.actions.create     }     export default connect(mapStateToProps, mapDispatchToProps)(Create) 
like image 402
jackD Avatar asked Nov 28 '17 21:11

jackD


People also ask

Why use Axios in react?

Why Use Axios in React? What is Axios? Axios is an HTTP client library that allows you to make requests to a given endpoint: This could be an external API or your own backend Node.js server, for example. By making a request, you expect your API to perform an operation according to the request you made.

What is Redux in ReactJS?

What is Redux? Redux is a state management library that helps us store our state to be accessible by each component. First, we need to install all these npm libraries for our react application.

How to use Axios in Redux?

axios is the promise so you need to use then to get your result. You should request your api in a separate file and call your action when the result comes back. You can dispatch an action in your then and it will update state when it gets a response from the axios call. I also think the best way to do this is by redux-axios-middleware.

How does async work in Redux?

Once that dispatched value reaches a middleware, it can make an async call, and then dispatch a real action object when the async call completes. Earlier, we saw a diagram that represents the normal synchronous Redux data flow.


2 Answers

Your redux action creators must be plain, object and should dispatch and action with a mandatory key type. However using custom middlewares like redux-thunk you could call axios request within your action creators as without custom middlewares your action creators need to return plain object

Your action creator will look like

export function create (values) {    return (dispatch) => {      dispatch({type: CREATE_ORGANIZATION});      axios.post('/url', values)            .then((res) =>{             dispatch({type: CREATE_ORGANIZATION_SUCCESS, payload: res});         })         .catch((error)=> {             dispatch({type: CREATE_ORGANIZATION_FAILURE, payload: error});         })   }  } 

and your reducer will look like

export default (state = initialState, action) => {   const payload = action.payload     switch (action.type) {         case CREATE:            return {         ...state,         loading: true,         loaded: false       }      case CREATE_SUCCESS:       return {         ...state,         data: state.data.concat(payload.data),         loading: false,         loaded: true,         error: null       }           }      case CREATE_FAILURE:        return {         ...state,         loading: false,         loaded: true,         error: payload       }     default:       return state   } } 

now while creating the store you can do it like

import thunk from 'redux-thunk'; import { createStore, applyMiddleware } from 'redux'; const store = createStore(   reducer,   applyMiddleware(thunk) ); 

Apart from this you also need to setUp the redux form

you need to use combineReducers and Provider to pass on the store

import reducer from './reducer'; import { combineReducers } from 'redux'; import { reducer as formReducer } from 'redux-form'  export const rootReducer = combineReducers({    reducer,    form: formReducer }) 

CodeSandbox

like image 191
Shubham Khatri Avatar answered Sep 19 '22 01:09

Shubham Khatri


You can do that easily with the help of redux-saga.

About redux-saga:

redux-saga is a library that aims to make application side effects (i.e. asynchronous things like data fetching and impure things like accessing the browser cache) easier to manage, more efficient to execute, simple to test, and better at handling failures.

Installation:

$ npm install --save redux-saga 

or

$ yarn add redux-saga

Please refer to the link : https://github.com/redux-saga/redux-saga

like image 34
Vikas Yadav Avatar answered Sep 22 '22 01:09

Vikas Yadav