Membuat Form Pada Aplikasi React – 1

Pada modul ini kita akan membahas penggunaan form pada aplikasi react.

Sebelum coding, ada baiknya kita desain dahulu form yang akan dibuat. Berikut desainnya:

  • Form akan digunakan baik untuk add atau edit.
  • Jika form dipanggil dengan id anime > 0 maka mode edit.
  • Jika form dipanggil dengan id anime = 0 maka mode add.

Dengan desain diatas, maka dapat disimpulkan untuk membuat route dengan admin/anime/:id dimana default link adalah admin/anime/0.

Untuk code form, sama dengan html biasa, namun sedikit perbedaan dalam memberikan attribute class, yaitu digunakan className.

Buat file baru src/components/AddEditAnime.js, tambahkan code berikut

import React, {Component, Fragment} from "react";

export default class AddEditAnime extends Component{
    constructor(props){
        super(props);
        this.state ={
            anime:{
                id:0,
                title: "",
                desc: "",
                year: "", 
            },
            isLoaded : false,
            error : null,
        }
        this.handleChg = this.handleChg.bind(this)
        this.handleSubm = this.handleSubm.bind(this)
    }

    handleSubm = (evt) =>{
        console.log("form submited");
        evt.preventDefault();
    }

    handleChg = (evt)=>{
        let value = evt.target.value;
        let name = evt.target.name;
        this.setState((prevstate)=>({
            anime:{
                ...prevstate.anime,
                [name] : value,
            }
        }));
    }

    componentDidMount(){        
        const id = this.props.match.params.id;
        if (id > 0){
            fetch("http://localhost:4000/v1/anime/" +id)
            .then((response)=>{
                if(response !== "200"){
                    let err = Error;
                    err.Message = "Invalid response code: " + response.status;
                    this.setState({error : err});
                }
                return response.json();
            })
            .then((json) => {
                this.setState({
                    anime:{
                        id: id,
                        title: json.anime.title,
                        year: json.anime.year,
                        desc: json.anime.desc,
                    },
                    isLoaded : true,
                },
                (error) => {
                    this.setState({
                        isLoaded : true,
                        error,
                    })
                }
                )
            })
        }else{
            this.setState({isLoaded:true});
        }
    }


    render(){
        let {anime, isLoaded, error} = this.state;
        if (error){
            return <div>Error : {error.Message}</div>
        }else if (!isLoaded){
            return <p>Loading...</p>
        }else{
            return(
                <Fragment>
                    <h2>Add/Edit Anime</h2>
                    <hr/>
                    <form onSubmit={this.handleSubm}>
                        <input type="hidden" name="id" id="id" value={anime.id} onChange={this.handleChg}/>
                        <div className="mb-3">
                            <label htmlFor="title" className="form-label">Title</label>
                            <input type="text" className="form-control" id="title" name="title" value={anime.title} onChange={this.handleChg}/>
                        </div>    
                        <div className="mb-3">
                            <label htmlFor="des" className="form-label">Description</label>
                            <textarea type="text" className="form-control" id="desc" name="desc" rows="3" onChange={this.handleChg} value={anime.desc}/>
                        </div>                    
                        <div className="mb-3">
                            <label htmlFor="year" className="form-label">Year</label>
                            <input type="text" className="form-control" id="year" name="year" value={anime.year} onChange={this.handleChg}/>
                        </div>
                        <hr/>
                        <button className="btn btn-primary">Save</button>
                    </form>
                    <div className="mt-3">
                        <pre>{JSON.stringify(this.state, null, 3)}</pre>
                    </div>
                </Fragment>
            );
        }


    }
}

Component form akan menggunakan method constructor untuk melakukan inisialisasi state dan data binding.

Cara kerja form pada aplikasi react agak sedikit berbeda, kita perlu menambahkan fungsi untuk event onChange dan onSubmit. Pada tutorial digunakan fungsi handleChg dan handleSubm.

Pada event componentDidMount, kita lakukan data retrieve, error checking dan assign data Anime.

Perhatian, bagian code berikut adalah untuk menampilkan isi form dalam format json. Sebagai debug sederhana. Pada hasil akhir akan dihapus.

<div className="mt-3">
    <pre>{JSON.stringify(this.state, null, 3)}</pre>
</div>

Pada src/App.js, lakukan penambahan impor untuk component form. Dan tambahkan routing.

import AddEditAnime from './components/AddEditAnime';
<li className="list-group-item"><Link to="/admin/anime/0">Add Anime</Link></li>
<Route path="/admin/anime/:id" component={AddEditAnime} />

Berikut isi lengkap src/App.js

import React from 'react';
import {BrowserRouter as Router, Switch, Route, Link} from 'react-router-dom';
import Home from './components/Home';
import Animes from './components/Animes';
import Admin from './components/Admin';
import Genres from './components/Genres';
import Anime from './components/Anime';
import Genre from './components/Genre';
import AddEditAnime from './components/AddEditAnime';

export default function App() {
  return (
  <Router>
    <div className="container">
      <div className="row">
          <h1 className="mt-3">Anime Collection</h1>
          <hr className="mb-3"/>
      </div>
      <div className="row">
          <div className="col-md-2">
              <nav>
                  <ul className="list-group">
                      <li className="list-group-item"><Link to="/">Home</Link></li>
                      <li className="list-group-item"><Link to="/animes">Anime</Link></li>
                      <li className="list-group-item"><Link to="/genres">Genre</Link></li>
                      <li className="list-group-item"><Link to="/admin/anime/0">Add Anime</Link></li>
                      <li className="list-group-item"><Link to="/admin">Admin</Link></li>
                  </ul>
              </nav>
          </div>
          <div className="col-md-10">
            <Switch>
              <Route path="/animes/:id" component={Anime} />
              <Route path="/animes"><Animes /></Route>
              <Route path="/genre/:id" component={Genre} />
              <Route exact path="/genres"><Genres /></Route>
              <Route path="/admin/anime/:id" component={AddEditAnime} />
              <Route path="/admin"><Admin /></Route>
              <Route path="/"><Home /></Route>
            </Switch>          
          </div>
      </div>
    </div>    
  </Router>
  );
}

Berikut tampilan akhir dari form, saat link dengan anime id=0, maka form dalam mode add. Ketika id>0 dan id tersebut ada didatabase, maka data akan diretrieve dan form dalam mode edit.

Pada modul selanjutnya kita akan membuat fungsi validasi pada client side.

Sharing is caring:

Leave a Comment