Membuat Simple Aplikasi Todo dengan React.js

Membuat Simple Aplikasi Todo dengan React.js

Membuat Simple Aplikasi Todo dengan React.js - Selamat pagi sobs sobs sekalian, semoga kalian dalam keadaan sehat walafiat pada kesempatan kali ini Gua akan sharing membuat aplikasi todo sederhana, sebelum itu buat sobs sekalian siapkan Kopi, Selonjorkan badan , Udut bagi yang udut, tentunya koneksi internet karena ditutorial kali ini tentunya wajib pakai internet.


Oh iya agar sobs-sobs mudah paham, saya sarankan sobs-sobs lebih dahulu mempelajari javascript fundamental, dan syntax dari jsx. jika belum ya engga apa-apa namanya juga belajar lama-lama kelamaan juga pasti paham.

Oke Tampilan hasil akhir kira-kira dari aplikasi sederhana yang akan kita buat kira-kira seperti dibawah ini




Pada tutorial kali ini kita tidak akan membuat project mengunakan create-react-app tapi hanya menggunakan CDN adapun komponen yang dibutuhkan yaitu React.js, ReactDOM, Babel.js dan tentunya saja pada kali ini menggunakan Bootstrap 5 untuk stylingnya.

Sebelum mulai kita, didalam aplikasi ini gua akan buat 3 komponen yaitu App, FormTodo dan Todo

- App : adalah komponen utama kita yang didalamnya terdapat 2 komponen lainya, nantinya komponen ini yang akan dirender.

- FormTodo : adalah komponen berupa form untuk menambahkan todo.

-Todo : adalah komponen berupa list dari todo yang sudah kita tambahkan.

oke kita mulai step by stepnya : 

1. Buatlah folder projectnya, silahkan dinamakan bebas.

2. Buat kopi, ett maksudnya buat file dengan extension .html,  nama file bebas sesuai dengan keinginan maka hasilnya seperti ini dan buka dengan text editor kesayangan anda boleh vim, nano atau vs code bebeas tentunya.




3. Kita Tambahkan CDN yang diperlukan dalam project kali ini seperti yang disebutkan diatas sobs dan buat element div yang berfungsi sebagai root project kita.

 
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Simple Todo</title>
    <!-- bootstrap css -->
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
      crossorigin="anonymous"
    />
  </head>
  <body>
    <div id="root"></div>

    <!-- React, ReactDOM, Babel.js dan bootstrap.js -->
    <script
      crossorigin
      src="https://unpkg.com/react@17/umd/react.development.js"
    ></script>
    <script
      crossorigin
      src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
    ></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
      crossorigin="anonymous"
    ></script>
  </body>
</html>

Jangan buru-buru dulu sobs, perhatikan disini menggunakan beberapa CDN yaitu Bootstrap, React, ReactDOM, dan Babel.js

5. Tambahkan kode berikut sebelum tag penutup body 
<script type="text/babel"> Ntar kode ditulis diantara tag ini </script>

nah seruput dulu kopinya,

6. Next adalah membuat constanta element id root, agar memudahkan kita dalam merender, sehingga menjadi seperti dibawah ini.

<script type="text/babel">
  // root element
  const rootElement = document.getElementById("root");
</script>

7. Buat Class App terlebih dahulu karena ini adalah parent yang membungkus komponen lainnya. didalamnya buat lagi constructor dan render method. nah didalam contructor ini kita buat state berupa array todo kita untuk default todonya kita isi statenya dengan array kosong saja.

class App extends React.Component {
   
   // tambahkan state disini
   constructor() {
     super();
     this.state = {
       todoList: [],
     };
   }

   // method untuk render html
   render() {}
}

Selanjutnya tambahkan kode dibawah ini didalam method render sehingga method render menjadi seperti dibawah ini


render() {
    return (
      <div className="container">
        {this.state.todoList.map((todo) => {
          return (
            <div key={todo.id}>
              {/* komponent Todo */}
              <Todo
                id={todo.id}
                text={todo.text}
                onHandleDeleteButton={this.handleDeleteButton}
              />
            </div>
          );
        })}
        {/* komponent FormTodo */}
        <FormTodo onAddTodo={this.addTodo} />
      </div>
    );
}

jika sobs sobs belum paham apa itu map, dan method render silahkan sobs-sobs mencari refrensi dengan membaca ditempat lain.
Next ...

8. Kita sementara selesai dulu dengan class App jangan diapa-apain terlebih dahulu ntar dia marah. berikutnya kita buat class baru yaitu class FormTodo, class ini berfungsi sebagai component untuk menambahkan todo,  codenya seperti dibawah ini : 


class FormTodo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      inputValue: "",
      pesanError: "",
    };
  }

  handleChangeInputValue = (e) => {
    this.setState({ inputValue: e.target.value });
  };

  handleSubmitForm = (e) => {
    e.preventDefault();
    if (this.state.inputValue.trim() === "") {
      this.setState({ pesanError: "Todo cannot empty !!!" });
    } else {
      this.props.onAddTodo(this.state.inputValue);
      this.setState({ inputValue: "", pesanError: "" });
    }
  };

  render() {
    // console.log(this.state.inputValue);
    return (
      <div className="row mt-5 justify-content-center">
        <div className="col-6">
          <form onSubmit={this.handleSubmitForm}>
            <div className="mb-3">
              <input
                type="text"
                value={this.state.inputValue}
                onChange={this.handleChangeInputValue}
                className="form-control"
                placeholder="Write todo here and Enter .."
              />
              {this.state.pesanError && (
                <div id="inputHelp" className="form-text text-danger">
                  {this.state.pesanError}
                </div>
              )}
            </div>
          </form>
        </div>
      </div>
    );
  }
}

Lanjut ke penjelasannya :

 - Method constructor : method ini adalah method yang pertama kali dijalankan pada saat pemanggilan object hasil inisialisasi dari class dimethod ini kita bisa melakuan inisialisasi property, selanjutnya method ini mempunyai parameter yaitu props, apaan tuh props ????, props adalah property yang dikirimkan dari parent class yaitu class App, lihat dimethod render class App maka akan dijumpai tulisan seperti ini <FormTodo onAddTodo={this.addTodo} /> nah onAddTodo merupakan property yang dikirimkan ke class FormTodo, sebenarnya props ini adalah optional artinya boleh ditulis atau tidak tergantung kebutuhan, lalu kapan menulisnya ? jika sobs-sobs ingin mengambil property yang dikirimkan dan mengelolanya didalam method constructor. kenapa disini ditulis hanya untuk biar ada penjelasan saja dan tulisan ini makin panjang, hehe gabut bet.

masih didalam method kesayangan kita ini, disini kita melakukan inisialisasi state, ada dua state yang diinisialisasi yaitu inputValue, dan pesanError. penjelasannya inputValue ini merupakan nilai atau value pada form artinya jika kita menuliskan kata apapun diform makan nilai dari form tersebut akan menjadi value dari state inputValue. misalnya sobat menuliskan "Saya ganteng" maka tulisan tersebut menjadi value dari state inputValue.
Next state pesanError state ini berisikan informasi tentang jika ada kesalahan dalam input form, misalnya sobs-sobs tidak menuliskan apapun namun sobs-sobs ingin menambahkannya. maka pesanError ini muncul dan todolist tidak akan ditambahkan, tidak semudah itu ferguso.

- Method handleChangeInput : oke method syantik ini berfungsi untuk melakukan update terhadap value state inputValue, misalkan sobs-sobs menekan huruf a dikeyboard maka nilai state inputValue menjadi a, selanjutnya sobs menekan lagi huruf b maka inputValue ab. untuk mengupdatenya yaitu dengan menggunakan this.setState()

- Method handleSubmitForm : oke method untuk menghandle form pada saat disubmit, dimethod ini akan dilakukan validasi apakah input yang kita masukan lolos tahap ujian. hehe nah didalam method ini state pesanError akan terupdate jika ujian tidak lulus. jika lulus maka todo ditambahkan dengan memanggil property yang dikirimkan parent class yaitu dengan keyword this.props, nah keyword ini cara kita mengambil property diluar method constructor. this.props.onAddTodo merupakan property berupa function oleh karena itu jika kita menuliskannya seperti ini this.props.onAddTodo() maka dia akan mengeksekusi method di parent class App yaitu addTodo. mungkin masih  sobs-sobs bingung karena method addTodo belum dibuat, nanti belakangan kita buat karena jagoan datangnya belakangan.
selanjutnya kita kosongkan nilai state inputValue dan pesanError.

9. Next yaitu kita buat class Todo yaitu class yang menampilkan list todo.


class Todo extends React.Component {
        render() {
          return (
            <div className="row mt-2 justify-content-center">
              <div className="col-6">
                <div className="card bg-dark text-white">
                  <div className="card-body">
                    <div className="row">
                      <div className="col-10 text-center">
                        {this.props.text}
                      </div>
                      <div className="col-2">
                        <button
                          type="button"
                          className="btn-close btn-sm btn-close-white float-end"
                          aria-label="Close"
                          id={this.props.id}
                          onClick={this.props.onHandleDeleteButton}
                        />
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          );
        }
}


diclass ini kita mengambil property yang dikirimkan oleh class parent yaitu class App.
- this.props.text : adalah isi dari todo.
- this.props.id : adalah identifier agar saat kita menghapus salah satu todo maka todolist di class App terhapus sesuai dengan idnya.
- this.props.onHandleDeleteButton : adalah property yang berupa function untuk meghapus todo pada saat diclick.

10. Next tambahkan method handleAddButton dan addTodo pada class App kita, sehingga full version dari class App kita menjadi seperti dibawah ini : 

class App extends React.Component {
        constructor() {
          super();
          this.state = {
            todoList: [],
          };
        }

        handleDeleteButton = (e) => {
          const newTodos = this.state.todoList.filter((todo) => {
            return todo.id !== e.target.id;
          });

          this.setState({
            todoList: newTodos,
          });
        };

        addTodo = (text) => {
          this.setState((prevState) => {
            return {
              todoList: [
                ...prevState.todoList,
                {
                  id: new Date().getTime().toString(),
                  text: text,
                },
              ],
            };
          });
        };

        render() {
          return (
            <div className="container">
              {this.state.todoList.map((todo) => {
                return (
                  <div key={todo.id}>
                    <Todo
                      id={todo.id}
                      text={todo.text}
                      onHandleDeleteButton={this.handleDeleteButton}
                    />
                  </div>
                );
              })}
              <FormTodo onAddTodo={this.addTodo} />
            </div>
          );
        }
      }

11. Sentuhan akhir tambahkan kode dibawah ini dibawah class App :

ReactDOM.render(<App />, rootElement);

kode diatas berfungsi untuk memasukan atau inner element class App ke dalam rootElement.

Sehingga keseluruhan code hasil akhir adalah seperti dibawah ini guys :


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Simple Todo</title>
    <!-- bootstrap css -->
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
      crossorigin="anonymous"
    />
  </head>
  <body>
    <div id="root"></div>

    <!-- React, ReactDOM, Babel.js dan bootstrap.js -->
    <script
      crossorigin
      src="https://unpkg.com/react@17/umd/react.development.js"
    ></script>
    <script
      crossorigin
      src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
    ></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
      crossorigin="anonymous"
    ></script>
    <script type="text/babel">
      // root element
      const rootElement = document.getElementById("root");

      class Todo extends React.Component {
        render() {
          return (
            <div className="row mt-2 justify-content-center">
              <div className="col-6">
                <div className="card bg-dark text-white">
                  <div className="card-body">
                    <div className="row">
                      <div className="col-10 text-center">
                        {this.props.text}
                      </div>
                      <div className="col-2">
                        <button
                          type="button"
                          className="btn-close btn-sm btn-close-white float-end"
                          aria-label="Close"
                          id={this.props.id}
                          onClick={this.props.onHandleDeleteButton}
                        />
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          );
        }
      }

      class FormTodo extends React.Component {
        constructor(props) {
          super(props);
          this.state = {
            inputValue: "",
            pesanError: "",
          };
        }

        handleChangeInputValue = (e) => {
          this.setState({ inputValue: e.target.value });
        };

        handleSubmitForm = (e) => {
          e.preventDefault();
          if (this.state.inputValue.trim() === "") {
            this.setState({ pesanError: "Todo cannot empty !!!" });
          } else {
            this.props.onAddTodo(this.state.inputValue);
            this.setState({ inputValue: "", pesanError: "" });
          }
        };

        render() {
          // console.log(this.state.inputValue);
          return (
            <div className="row mt-5 justify-content-center">
              <div className="col-6">
                <form onSubmit={this.handleSubmitForm}>
                  <div className="mb-3">
                    <input
                      type="text"
                      value={this.state.inputValue}
                      onChange={this.handleChangeInputValue}
                      className="form-control"
                      placeholder="Write todo here and Enter .."
                    />
                    {this.state.pesanError && (
                      <div id="inputHelp" className="form-text text-danger">
                        {this.state.pesanError}
                      </div>
                    )}
                  </div>
                </form>
              </div>
            </div>
          );
        }
      }

      class App extends React.Component {
        constructor() {
          super();
          // tambahkan state disini
          this.state = {
            todoList: [],
          };
        }

        handleDeleteButton = (e) => {
          const newTodos = this.state.todoList.filter((todo) => {
            return todo.id !== e.target.id;
          });

          this.setState({
            todoList: newTodos,
          });
        };

        addTodo = (text) => {
          this.setState((prevState) => {
            return {
              todoList: [
                ...prevState.todoList,
                {
                  id: new Date().getTime().toString(),
                  text: text,
                },
              ],
            };
          });
        };

        // method untuk render html
        render() {
          return (
            <div className="container">
              {this.state.todoList.map((todo) => {
                return (
                  <div key={todo.id}>
                    {/* komponen Todo */}
                    <Todo
                      id={todo.id}
                      text={todo.text}
                      onHandleDeleteButton={this.handleDeleteButton}
                    />
                  </div>
                );
              })}

              {/* komponen FormTodo */}
              <FormTodo onAddTodo={this.addTodo} />
            </div>
          );
        }
      }

      ReactDOM.render(<App />, rootElement);
    </script>
  </body>
</html>

Oke sobs sobs sekalian gua sadar bahwa tulisan ini masih banyak kekurangan. oleh karena itu silahkan berkomentar jika ada masukan atau ada yang ingin ditanyakan. untuk sorce code dan demo bisa kunjungi disini .


See you next time.

Posting Komentar untuk "Membuat Simple Aplikasi Todo dengan React.js"

www.domainesia.com
Web Hosting
www.domainesia.com