React – Posting Form Data

Photo by Lukas from Pexels

This is an example of a single component with a form that submits data to an API. A single Class component will display the form and handle the state and API call. The API used in this example is jsonplaceholder.typecode.com

https://jsonplaceholder.typicode.com/posts

The jsonplaceholder.typecode.com api can take up to 3 fields,
title, body, userid and will return id, title, body, userid in the console.

Imports needed. Using axios for the API call.

import React, { Component } from 'react';
import axios from 'axios';

Create a class component.

import React, { Component } from 'react';
import axios from 'axios';

class PostForm extends Component {

  constructor(props) {
        super(props);
        this.state = {
            userId: 1,
            title: '',
            body: ''
       };
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
  }
handleChange(event) {
   this.setState({value: event.target.value});
}
    render() {
    }
}

Optional: Render the form. Using React.Fragment instead of wrapping it with a <div> tag which is optional.

      return (
          <React.Fragment>          
          <form onSubmit={this.handleSubmit}>
        
            <input 
                name="title"
                type="text"
                placeholder="Title"
                onChange={this.handleInputChange}/>
           
          <br />
          
          <input 
                name="body"
                type="text"
                placeholder="Title"
                onChange={this.handleInputChange}/>

            
                <br></br>
            <input type="submit">Save</input>   
     
         
        </form>
        </React.Fragment>
      );
    }

Above the render() event add the handleInputChange() function. This function will set the state and can be called by text and radio button fields.

  handleInputChange(event) {
        const target = event.target;
        const value = target.type === 'checkbox' ? target.checked : target.value;
        const name = target.name;
    
        this.setState({
          [name]: value
        });
        // If you want to see the actual state changes
        console.log('Input change ',value, name );
     }

Finally add a function to post the data via API call.


handleSubmit(event) {
  event.preventDefault();     
  axios.post('https://jsonplaceholder.typicode.com/posts', ({userid: this.state.userId, title: this.state.title,   body: this.state.body})) 
    .then(res => {
      console.log(res);
      console.log(res.data);
      
    })
}

Setting up Axios

Using the constants defined in the .env file located at the root of the React-App. All the calls in the component will have the domain in the baseURL. Click here for more information on this.

if (process.env.NODE_ENV === 'development') {
  axios.defaults.baseURL = process.env.REACT_APP_BASE_URL_LOCAL;            
} else {
  axios.defaults.baseURL = process.env.REACT_APP_BASE_URL_PROD;
}   

Posting Files

For posting files, the API is expecting a different format, In the example below uses a Dropzone.

import { DropzoneArea } from 'material-ui-dropzone'
...

handleDropzoneChange(files) {       
   this.setState({ files: files });
}

...
<DropzoneArea onChange={this.handleDropzoneChange.bind(this)} />

Use axios as follows.

  handleSubmitForm = (event) => {        
        let formData = new FormData();

        formData.append("Name", this.state.Name);
        formData.append("Title", this.state.Title);
        formData.append("Details", this.state.Details);

        // Get all images from Material-Dropzone
        for (let i = 0; i < this.state.files.length; i++) {
            formData.append(`images[${i}]`, this.state.files[i])
        }        

        const url = `/api/pub/addrecordwithimages`;                

        axios({
            method: 'post',
            url: url,
            data: formData,
            headers: {'Content-Type': 'multipart/form-data' }
        })
        .then(function (response) {
            //handle success
            console.log(response);
        })
        .catch(function (response) {
            //handle error
            console.log(response);
        });
          
    }