Apa saja yang akan dibahas?
Yuk kita mengingat lagi tentang pembuatan ToDoList kemarin yah
Bagaimana bila seandainya sekarang kita ingin membuat ToDoList dalam bentuk sebuah tabel ?
Mari kita coba untuk membuatnya yah !
npx create-react-app nama-project-yang-diinginkan
div className="App"
) saja
File ToDo.jsx
import React, { useState } from "react";
function ToDo() {
// Sekarang state kita berbentuk array of object !
const [todos, setTodos] = useState([
{ id: 1, name: "Review DOM", isCompleted: true },
{ id: 2, name: "Belajar Nge-React", isCompleted: false },
{ id: 3, name: "Belajar Component React", isCompleted: false },
]);
return (
<>
<div>Aplikasi ToDo</div>
</>
);
}
export default ToDo;
Apabila saat di save keluar warning di linter, abaikan terlebih dahulu yah !
Selanjutnya kita akan memodifikasi file App.js untuk menampilkan containers ToDo
File App.js
import React from "react";
import ToDo from "./containers/ToDo.jsx";
function App() {
return (
<div className="App">
<ToDo />
</div>
);
}
export default App;
Selanjutnya kita akan mulai untuk membuat component ToDoForm
File ToDoForm.jsx
import React, { useState } from "react";
function ToDoForm(props) {
const [inputData, setInputData] = useState("");
const inputOnChangeHandler = (event) => {
setInputData(event.target.value);
};
const formOnSubmitHandler = (event) => {
event.preventDefault(); // nanti akan ditambah lagi yah !
};
return (
<form style={{ margin: "0.5em 0em" }} onSubmit={formOnSubmitHandler}>
<input
type="text"
style={{ marginRight: "0.5em" }}
placeholder="Input kerjaan baru"
value={inputData}
onChange={inputOnChangeHandler}
/>
<button type="submit">Tambah kerjaan</button>
</form>
);
}
export default ToDoForm;
Wah kode kita sudah mulai panjang yah !
Ya, memang seperti inilah bila sudah masuk ke React yah, harus menerima sikon yang seperti ini !
Selanjutnya kita akan mulai membuat component ToDoTable yah !
File ToDoTable.jsx
import React from "react";
function ToDoTable(props) {
return (
<table>
<thead>
<tr>
<th>ToDo Id</th>
<th>ToDo Name</th>
<th>ToDo Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{props.todos.map((todo) => ( // asumsi nama props yang dilempar adalah todos
<tr key={todo.id}>
<td>{todo.id}</td>
<td>{todo.name}</td>
<td>{todo.isCompleted ? "Selesai" : "Belum Selesai"}</td>\
<td>{todo.isCompleted ? "" : <button>Selesaikan</button>}</td>
</tr>
))}
</tbody>
</table>
);
}
export default ToDoTable;
Selanjutnya kita akan modifikasi file ToDo.jsx kembali, untuk menambahkan ToDoForm dan ToDoTable
import React, { useState } from "react";
// Import ToDoForm dan ToDoTable
import ToDoForm from "../components/ToDoForm.jsx";
import ToDoTable from "../components/ToDoTable.jsx";
function ToDo() {
...
return (
<>
<div>Aplikasi ToDo</div>
{/* Kita tambahkan component ToDoForm dan ToDoTable */}
{/* Jangan lupa untuk passing props todos ke dalam ToDoTable */}
<ToDoForm />
<ToDoTable todos={todos} />
</>
);
}
...
Apakah sampai di sini sudah selesai? Tentu saja tydaque !
Sekarang kita akan membuat logic untuk menambahkan data todos ke dalam tabel apabila tombol Tambah kerjaan ditekan !
File ToDo.jsx
...
function ToDo() {
...
const addTodos = (newTodo) => {
// Logic untuk membuat id terbaru
// ambil dari object paling akhir punya id, tambahkan 1
const newId = todos[todos.length - 1].id + 1;
const objTodo = {
id: newId,
name: newTodo,
isCompleted: false,
};
const newTodos = [...todos, objTodo]; // perhatikan di sini tambah object dengan spread
setTodos(newTodos); // set array yang baru dengan newTodos
};
return (
...
{/* Kita tambahkan component ToDoForm dan ToDoTable */}
{/* Jangan lupa untuk passing props todos ke dalam ToDoTable */}
<ToDoForm fnAddTodos={addTodos} />
<ToDoTable todos={todos} />
...
Selanjutnya kita akan modifikasi component ToDoForm
File ToDoForm.jsx
...
const formOnSubmitHandler = (event) => {
event.preventDefault();
// Panggil props fnAddTodos
props.fnAddTodos(inputData);
// Kosongkan lagi input
setInputData("");
};
...
Sampai di titik ini artinya kita sudah selesai untuk membuat penambahan data todos ke dalam tabel !
Selanjutnya kita akan membuat logic untuk menyelesaikan todos yang sudah dibuat !
Apabila tombol selesaikan dalam tiap baris data ditekan, maka akan membuat data isCompleted menjadi true
Mari kita mulai dari modifikasi container ToDo
File ToDo.jsx
function ToDo() {
...
// Fungsi ini akan membuat sebuah array yang bar dan memodifikasi satu baris
// data yang ditemukan untuk membuat isCompleted nya menjadi true
// berdasarkan idTodo yang diterima
const completeTodo = (idTodo) => {
const newTodos = todos.map((todo) => {
if (todo.id === idTodo) {
todo.isCompleted = true;
}
return todo;
});
setTodos(newTodos);
};
return (
<>
...
{/* Jangan lupa tambahkan props fnCompleteToDo ke dalam table */}
<ToDoTable todos={todos} fnCompleteTodo={completeTodo} />
</>
);
}
Selanjutnya, modifikasi component ToDoTable untuk menyelesaikan todos yang sudah dibuat !
File ToDoTable.jsx
...
function ToDoTable(props) {
// Perhatikan fungsi ini tidak menerima event
const btnOnClickHandler = (todoId) => {
// di sini kita akan memanggil props fnCompleteTodo
// beserta value todoId akan dilempar
props.fnCompleteTodo(todoId);
};
return (
...
<td>
{todo.isCompleted ? (
""
) : (
// onClick di sini akan menggunakan fungsi arrow
// untuk bisa memanggil fungsi btnOnClickHandler
// sambil passing value todo.id
<button onClick={() => btnOnClickHandler(todo.id)}>
Selesaikan
</button>
)}
</td>
...
);
Sampai di sini artinya kita sudah menyelesaikan semuanya !
Wah ternyata panjang yah !
Tenang... kalau sudah bekerja pastinya lebih panjang dari ini kok !
Tapi, ngomong-ngomong soal kerja, ini masih ada yang kurang loh...
Ya ! kita belum melakukan styling agar component kita menjadi lebih baik !
Untuk bisa melakukan styling terhadap component sebenarnya kita bisa saja melakukannya secara manual
Tapi bagaimana bila ternyata sudah ada yang mau berbaik hati membuatkan styling-nya, bahkan sampai sudah membuatkannya dalam bentuk Component-based ?
Yuk, tanpa bak bik buk, kita coba melihatnya !
UI Component Library umumnya adalah sekumpulan UI Component yang sudah siap digunakan untuk membuat sebuah aplikasi web.
Contoh Component, e.g.: Button, Input, Dialog, dsb
Dibuat sebagai library untuk membangun tampilan yang baik dan konsisten !
Contoh UI Component Library untuk React adalah:
Yang akan kita gunakan pada pembelajaran ini adalah MUI
MUI adalah UI Component Library yang didesain berdasarkan Material Design yang dibuat oleh Google.
Punya tampilan yang Google-alike, sehingga cukup cocok untuk tampilan mobile based (dan juga) secara visual akan cocok untuk tampilan desktop based.
Akan tetapi, bila nantinya tidak dicustom dengan baik, akan dikira sebagai aplikasi yang jadi produknya Google !
Yuk kita langsung buka MUI dan mulai belajar menggunakannya !
Tautan untuk penggunaan MUI bisa dibuka dengan Klik di sini
Mari kita kembali lagi ke project ToDo yang kita buat tadi
Sekarang kita akan menambahkan UI Library MUI ke dalam project yang sudah kita buat
Untuk menambahkannya kita bisa menggunakan perintah di bawah
npm install @mui/material @emotion/react @emotion/styled
Nah, setelah menambahkan package ini, saatnya kita menggunakan MUI di dalam project kita !
Kita mulai dari file ToDoForm.jsx, dan menambahkan component Button MUI untuk menggantikan button standar yang kita buat sebelumnya
import React, { useState } from "react";
import Button from "@mui/material/Button"; // tambahkan ini untuk import button
function ToDoForm(props) {
...
return (
<form style={{ margin: "0.5em 0em" }} onSubmit={formOnSubmitHandler}>
...
{/* Ganti button menjadi Button dengan opsi baru */}
<Button type="submit" variant="contained" size="large">
Tambah kerjaan
</Button>
</form>
);
}
Perhatikan di sini ada attribute baru dengan nama variant dan size, ini merupakan attribute tambahan dari Button MUI.
Untuk Dokumentasi Button MUI dapat dilihat di sini
Selanjutnya kita akan freestyle menambahkan component MUI !
File ToDoForm.jsx
import React, { useState } from "react";
import Button from "@mui/material/Button";
// Import component TextField dari MUI (kali ini kita gunakan destructuring)
import { TextField } from "@mui/material";
function ToDoForm(props) {
...
return (
<form
style={{
margin: "0.5em 0em",
// Tambah css agar bisa sama besar component TextField dan Button
display: "flex",
}}
onSubmit={formOnSubmitHandler}
>
{/* Ganti input menjadi TextField */}
<TextField
type="text"
style={{ marginRight: "0.5em" }}
value={inputData}
onChange={inputOnChangeHandler}
// ini prop (attribute) baru
label="Input kerjaan baru"
size="small"
variant="filled"
/>
...
File ToDo.jsx
import React, { useState } from "react";
...
// Import component Typography dari MUI
import { Typography } from "@mui/material";
function ToDo() {
...
return (
<>
{/* Ganti div menjadi Typography */}
<Typography variant="h5">Aplikasi ToDo</Typography>
...
</>
);
}
export default ToDo;
Dokumentasi TextInput dapat dilihat di sini
Dokumentasi Typography dapat dilihat di sini
File ToDoTable.jsx
import React from "react";
// Import Component MUI di sini
import {
Button, Table, TableHead, TableBody, TableRow, TableCell,
} from "@mui/material";
function ToDoTable(props) {
...
return (
// Gunakan Component MUI di sini
// di sini kita menggunakan sx untuk definisi style
<Table sx={{ maxWidth: 650 }}>
{/* Ganti thead => TableHead */}
{/* Ganti tbody => TableBody */}
{/* Ganti tr => TableRow */}
{/* Ganti th dan td => TableCell */}
{/* Ganti button => Button */}
</Table>
);
}
Dokumentasi Table dapat dilihat di sini
Wah panjang sekali yah kodenya?
Tenang, projekan biasanya lebih dari ini kok !
Bagi yang tertinggal mengikuti materi ini, atau males mau langsung liat akhirnya aja, bisa ngintip kode finalnya di sini !
Atau bagi yang mau langsung mencoba demonya, bisa dibuka di Stackblitz