Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React - how to rerender component after POST data to database (mongodb)

I'm building app which sends data to my database (mongodb). In ComponentDidMount I fetch data from this database, save them in this.state and show them in frontend. Next, I want to add another single data to this database from form in frontend. For now it works fine, couse this single data is added to database, but I have to refresh page to see new-added data.

So, I'm wondering how to show dynamically in frontend newly added item to database.

My first thoughts were something with component lifecycle, or maybe some function which fetch data after submit form, but this won't work.

Any ideas?

Here is my code:

import React, { Component } from 'react';
import axios from 'axios';
import Users from './Users';

class Main extends Component {
    constructor(props) {
        super(props);

        this.state = {
            users: [],
            group: '',
            password: '',
            firstName: '',
            lastName: '',
            dateOfBirth: '',
            listOfUserGroups: ''
        };

        this.handleSubmit = this.handleSubmit.bind(this);
    }

    componentDidMount() {
        axios.get('http://localhost:3001/users')
          .then(res => {
            const users = res.data;
            this.setState({ users });
            console.log(this.state.users);
          })
    }

    handleGroupChange = e => {
        this.setState({ group: e.target.value });
    }

    handlePasswordChange = e => {
        this.setState({ password: e.target.value });
    }

    handleFirstNameChange = e => {
        this.setState({ firstName: e.target.value });
    }

    handleLastNameChange = e => {
        this.setState({ lastName: e.target.value });
    }

    handleDateOfBirthChange = e => {
        this.setState({ dateOfBirth: e.target.value });
    }

    handleListOfUserGroupsChange = e => {
        this.setState({ listOfUserGroups: e.target.value });
    }

    handleSubmit(e) {
        e.preventDefault();

        const newUser = {
            group: this.state.group,
            password: this.state.password,
            firstName: this.state.firstName,
            lastName: this.state.lastName,
            dateOfBirth: this.state.dateOfBirth,
            listOfUserGroups: this.state.listOfUserGroups
        };

        axios.post('http://localhost:3001/users', newUser)
            .then(response => {
                console.log('Saved');
                console.log(response.data);
                console.log(this.state.firstName);
            });
    }

    render() {
        return (
            <div>

                <div className='mainWrapper'>
                  <form className='formStyle' onSubmit={this.handleSubmit}>
                      <label>Group</label>
                      <input type="text" onChange={this.handleGroupChange} />

                      <label>Password</label>
                      <input type="text" onChange={this.handlePasswordChange} />

                      <label>First name</label>
                      <input type="text" onChange={this.handleFirstNameChange} />

                      <label>Last name</label>
                      <input type="text" onChange={this.handleLastNameChange} />

                      <label>Date of birth</label>
                      <input type="text" onChange={this.handleDateOfBirthChange} />

                      <label>List of user groups</label>
                      <input type="text" onChange={this.handleListOfUserGroupsChange} />

                      <button type="submit">Add</button>
                  </form>
                </div>

                <Users users={this.state.users} />

                <div>
                    <ul>
                        <li>{this.state.group}</li>
                        <li>{this.state.password}</li>
                        <li>{this.state.firstName}</li>
                        <li>{this.state.lastName}</li>
                        <li>{this.state.dateOfBirth}</li>
                        <li>{this.state.listOfUserGroups}</li>
                    </ul>
                </div>

            </div>
        );
    }
}

export default Main;
like image 651
Mevitth Avatar asked Apr 27 '18 08:04

Mevitth


2 Answers

Just push to the array to make the update to the state and it will rerender.

 handleSubmit(e) {
    e.preventDefault();

    const newUser = {
        group: this.state.group,
        password: this.state.password,
        firstName: this.state.firstName,
        lastName: this.state.lastName,
        dateOfBirth: this.state.dateOfBirth,
        listOfUserGroups: this.state.listOfUserGroups
    };

    axios.post('http://localhost:3001/users', newUser)
        .then(response => {
            console.log('Saved');
            this.setState(prevState=>({
              users: [newUser, ...prevState.users]
            }))
            console.log(response.data);
            console.log(this.state.firstName);
        });
}

Or if necessary, you can push to the state before the axios call and revert back only if the call fails. This is called Optimistic UI

Note: You can handle multiple input change like this

like image 158
Agney Avatar answered Nov 11 '22 04:11

Agney


You need to update your state on your post response. By default, when your component’s state or props change, your component will re-render.

Solution 1 :

axios.post('http://localhost:3001/users', newUser)
        .then(response => {
            console.log(response.data); //need to be your new "user" from server response
        //You can update your "users" state there with add new user in your state
        });

Solution 2:

axios.post('http://localhost:3001/users', newUser)
        .then(response => {
            console.log(response.data); //need to be your new "user" from server response
            //You can send your "get" request again to update your component state
            axios.get('http://localhost:3001/users')
                .then(res => {
                const users = res.data;
                this.setState({ users });
                console.log(this.state.users);
            })
        });
like image 1
LaPoule Avatar answered Nov 11 '22 05:11

LaPoule