Như tiêu đề bài viết, nội dung trong bài viết này của mình sẽ tạo một form basic sử dụng Material UI, ReactJS và Typescript. Vậy điều đầu tiên tại sao chúng ta lại cần typescript? Typescript hoạt động ra sao?
Lý do đơn giản để sử dụng typescript đó là nếu bạn muốn code chặt chẽ hơn giữa các data type, có một sự đồng bộ giữa các member trong project thì hãy lên sử dụng typescript.
Thực chất bạn không phải là học thêm một ngôn ngữ lập trình mới mà typescript sẽ được transform qua javascript thông qua Babel và code của chúng ta vẫn là javascript như trước kia.
Yêu cầu:
tạo form cho 2 loại input text và checkbox + submit button
dữ liệu khi submit form có dạng (chỉ cần console.log trong hàm thực thi): {categories: [1, 2, 3, 4], meta: ["a", "b", "c"]}
meta ko được chứa dữ liệu rỗng
cho phép add or remove input text
multi checkbox
2. Demo
Trước khi demo thì chúng ta cũng cần có các kiến thức cơ bản:
Basic types, các bạn chỉ cần dành thêm 5 phút để đọc chúng.
Đối với file index.js đơn giản chúng ta chỉ cần inport component Form mà chúng ta sẽ custom ngay bây giờ:
import React from 'react';
import ReactDOM from 'react-dom';
import { ThemeProvider } from '@material-ui/core/styles';
import { theme } from './theme';
import { Form } from './form';
ReactDOM.render(
<ThemeProvider theme={theme}>
<Form />
</ThemeProvider>,
document.querySelector('#root')
);
import React, { useState } from "react";
import { Grid } from "@material-ui/core";
...
export function Form() {
return (
<>
<Grid container direction="column">
Hello!
</Grid>
</>
);
}
Oke, giờ ta làm trước phần multi checkbox xem sao nhé, thay vì fix cứng data checkbox mình sẽ giả dụ như chúng ta đang có 1 cục data được server trả về như sau:
Ở trên mình có pass categories qua một component khác mục đích đó là chúng ta sẽ xử lý tất cả ở trong component form.tsx và pass lại các hàm thực thi qua bên FormComponent, làm như vậy theo mình code sẽ được clean hơn rất nhiều.
Các bạn có thấy mình thêm 1 props handleChange vào trong FormComponent không? và nó được sử dụng để lấy id checkbox đã được click. Mục đích để chúng ta lấy các giá trị checkbox đã được chọn. Ok tiếp theo ta qua form.tsx và handle function handleChange:
...
export function Form() {
//tạo một state chứa các checkbox được chọn
const [categoriesSelector, setCategoriesSelectors] = useState([]);
const handleChange = (currentCheckBoxSelectored: number) => () => {
//so sánh xem nếu category được chọn đã có trong state `categoriesSelector` chưa
if (categoriesSelector.includes(currentCheckBoxSelectored)) {
//nếu rồi thì tìm vị trí của nó theo tên phần tử `currentCheckBoxSelectored` và xóa nó đi
let arrCheckBoxSelectored = [...categoriesSelector];
arrCheckBoxSelectored.splice(
categoriesSelector.indexOf(currentCheckBoxSelectored),
1
);
setCategoriesSelectors(arrCheckBoxSelectored);
} else {
//còn chưa thì chúng ta sẽ thêm nó vào `categoriesSelector`
let arrCheckBoxSelectored = [
...categoriesSelector,
currentCheckBoxSelectored
];
setCategoriesSelectors(arrCheckBoxSelectored);
}
};
...
<Grid container direction="column">
<FormComponent
categories={categories}
handleChange={handleChange}
/>
</Grid>