Cách tạo ứng dụng quản lý danh sách khách hàng với React và TypeScript
TypeScript đã mang lại nhiều cải tiến về cách các nhà phát triển JavaScript cấu trúc và viết mã cho các ứng dụng, đặc biệt là các ứng dụng web. Được định nghĩa là một tập hợp siêu JavaScript, TypeScript hoạt động giống hệt JavaScript nhưng với các tính năng bổ sung được thiết kế để giúp các nhà phát triển xây dựng các chương trình lớn hơn và phức tạp hơn với ít hoặc không có lỗi. TypeScript ngày càng trở nên phổ biến; được các công ty lớn như Google áp dụng cho khung web Angular. Khung back-end Nest.js cũng được xây dựng bằng TypeScript.Một trong những cách để cải thiện năng suất với quyền là nhà phát triển là khả năng triển khai các tính năng mới nhanh nhất có thể mà không phải lo lắng về việc phá vỡ ứng dụng hiện có trong quá trình production . Để làm điều này, viết mã được nhập tĩnh là một phong cách được nhiều nhà phát triển dày dạn áp dụng. Các ngôn ngữ lập trình được định kiểu tĩnh như TypeScript thực thi một liên kết cho mọi biến có kiểu dữ liệu; chẳng hạn như một chuỗi, số nguyên, boolean, v.v. Một trong những lợi ích chính của việc sử dụng ngôn ngữ lập trình kiểu tĩnh là việc kiểm tra kiểu được hoàn thành tại thời điểm biên dịch, do đó các nhà phát triển có thể thấy lỗi trong mã của họ ở giai đoạn rất sớm.
React là một thư viện JavaScript open-souce , mà các nhà phát triển sử dụng để tạo giao diện user cao cấp cho các ứng dụng web có thể mở rộng. Hiệu suất tuyệt vời và giao diện user động được xây dựng bằng React cho các ứng dụng một trang khiến nó trở thành lựa chọn phổ biến của các nhà phát triển.
Trong hướng dẫn này, bạn sẽ tạo một ứng dụng quản lý danh sách khách hàng với phần backend REST API riêng biệt và giao diện user được xây dựng bằng React và TypeScript. Bạn sẽ xây dựng chương trình backend bằng cách sử dụng một API REST giả có tên là json-server
. Bạn sẽ sử dụng nó để nhanh chóng cài đặt chương trình backend CRUD (Tạo, Đọc, Cập nhật và Xóa). Do đó, bạn có thể tập trung vào việc xử lý logic front-end của một ứng dụng bằng React và TypeScript.
Yêu cầu
Để hoàn thành hướng dẫn này, bạn cần :
Một cài đặt local của Node.js (ít nhất là v6) và
npm
(ít nhất là v5.2). Node.js là một môi trường thời gian chạy JavaScript cho phép bạn chạy mã của bạn bên ngoài trình duyệt. Nó đi kèm với một trình quản lý gói được cài đặt sẵn có tên lànpm
, cho phép bạn cài đặt và cập nhật các gói. Để cài đặt chúng trên macOS hoặc Ubuntu 18.04, hãy làm theo các bước trong Cách cài đặt Node.js và Tạo môi trường phát triển local trên macOS hoặc phần “Cài đặt bằng PPA” của Cách cài đặt Node.js trên Ubuntu 18.04 .Một cài đặt local của Yarn; làm theo các bước sau để cài đặt Yarn trên hệ điều hành của bạn.
Hiểu biết cơ bản về TypeScript và JavaScript .
Đã cài đặt một editor ; chẳng hạn như Mã Visual Studio , Atom hoặc Sublime Text .
Bước 1 - Cài đặt TypeScript và tạo ứng dụng React
Trong bước này, bạn sẽ cài đặt gói TypeScript trên phạm vi global trên máy của bạn bằng cách sử dụng Node Package Manager ( npm
). Sau đó, bạn cũng sẽ cài đặt React và các phụ thuộc của nó và kiểm tra xem ứng dụng React của bạn có đang hoạt động hay không bằng cách chạy server phát triển.
Để bắt đầu, hãy mở một terminal và chạy lệnh sau để cài đặt TypeScript:
- npm install -g typescript
Khi cài đặt xong , hãy thực hiện lệnh sau để kiểm tra cài đặt TypeScript của bạn:
- tsc -v
Bạn sẽ thấy version hiện tại được cài đặt trên máy của bạn :
OutputVersion 3.4.5
Tiếp theo, bạn sẽ cài đặt ứng dụng React bằng cách sử create-react-app
công cụ create-react-app
để cài đặt ứng dụng với một lệnh duy nhất. Bạn sẽ sử dụng lệnh npx
, là một công cụ chạy gói đi kèm với npm
. Công cụ create-react-app
có hỗ trợ tích hợp để làm việc với TypeScript mà không cần bất kỳ cấu hình bổ sung nào. Chạy lệnh sau để tạo và cài đặt một ứng dụng React mới có tên là typescript-react-app
:
- npx create-react-app typescript-react-app --typescript
Lệnh trước đó sẽ tạo một ứng dụng React mới với tên là typescript-react-app
. Cờ --typescript
sẽ đặt loại file mặc định cho các thành phần React thành .tsx
.
Trước khi bạn hoàn thành phần này, ứng dụng sẽ yêu cầu chuyển từ cổng này sang cổng khác. Để làm điều đó, bạn cần cài đặt một thư viện định tuyến cho ứng dụng React của bạn có tên là React Router và các định nghĩa TypeScript tương ứng của nó. Bạn sẽ sử dụng yarn
để cài đặt thư viện và các gói khác cho dự án này. Điều này là do yarn
nhanh hơn, đặc biệt là để cài đặt các phụ thuộc cho ứng dụng React. Di chuyển vào folder dự án mới được tạo và sau đó cài đặt Bộ định tuyến React bằng lệnh sau:
- cd typescript-react-app
- yarn add react-router-dom
Đến đây bạn đã có gói React Router, gói này sẽ cung cấp chức năng định tuyến trong dự án của bạn. Tiếp theo, chạy lệnh sau để cài đặt định nghĩa TypeScript cho Bộ định tuyến React:
- yarn add @types/react-router-dom
Bây giờ, bạn sẽ cài đặt axios
, một ứng dụng HTTP dựa trên hứa hẹn dành cho các trình duyệt, để trợ giúp quá trình thực hiện các yêu cầu HTTP từ các thành phần khác nhau mà bạn sẽ tạo trong ứng dụng:
- yarn add axios
Khi cài đặt xong , hãy khởi động server phát triển với:
- yarn start
Ứng dụng của bạn sẽ chạy trên http://localhost:3000
.
Bạn đã cài đặt thành công TypeScript, tạo một ứng dụng React mới và cài đặt React Router để giúp chuyển từ trang này sang trang khác của ứng dụng. Trong phần tiếp theo, bạn sẽ cài đặt server back-end cho ứng dụng.
Bước 2 - Tạo server JSON
Trong bước này, bạn sẽ tạo một server giả để ứng dụng React của bạn có thể nhanh chóng kết nối, cũng như sử dụng các tài nguyên của nó. Điều quan trọng cần lưu ý là dịch vụ back-end này không thích hợp cho một ứng dụng trong production . Bạn có thể sử dụng Nest.js, Express hoặc bất kỳ công nghệ back-end nào khác để xây dựng API RESTful trong quá trình production . json-server
là một công cụ hữu ích khi nào bạn cần tạo một nguyên mẫu và giả lập một server back-end.
Bạn có thể sử dụng npm
hoặc yarn
để cài đặt json-server
trên máy của bạn . Điều này sẽ làm cho nó có sẵn từ bất kỳ folder nào trong dự án của bạn khi nào bạn có thể cần sử dụng nó. Mở một cửa sổ terminal mới và chạy lệnh này để cài đặt json-server
trong khi bạn vẫn ở trong folder dự án:
- yarn global add json-server
Tiếp theo, bạn sẽ tạo một file JSON chứa dữ liệu sẽ được hiển thị bởi API REST. Đối với các đối tượng được chỉ định trong file này (mà bạn sẽ tạo), điểm cuối CRUD sẽ được tạo tự động. Để bắt đầu, hãy tạo một folder mới có tên là server
và sau đó chuyển vào đó:
- mkdir server
- cd server
Bây giờ, sử dụng nano
để tạo và mở một file mới có tên db.json
:
- nano db.json
Thêm nội dung sau vào file :
{ "customers": [ { "id": 1, "first_name": "Customer_1", "last_name": "Customer_11", "email": "customer1@mail.com", "phone": "00000000000", "address": "Customer_1 Address", "description": "Customer_1 description" }, { "id": 2, "first_name": "Customer_2", "last_name": "Customer_2", "email": "customer2@mail.com", "phone": "00000000000", "address": "Customer_2 Adress", "description": "Customer_2 Description" } ] }
Cấu trúc JSON bao gồm một đối tượng khách hàng, có hai tập dữ liệu được gán. Mỗi khách hàng bao gồm bảy thuộc tính: id
, description
, first_name
, last_name
, email
, phone
và address
.
Lưu và thoát khỏi file .
Theo mặc định, json-server
chạy trên cổng 3000
— đây cũng là cổng mà ứng dụng React của bạn chạy trên đó. Để tránh xung đột, bạn có thể thay đổi cổng mặc định cho json-server
. Để làm điều đó, hãy chuyển đến folder root của ứng dụng:
- cd ~/typescript-react-app
Mở ứng dụng bằng editor bạn muốn và tạo một file mới có tên json-server.json
:
- nano json-server.json
Bây giờ hãy chèn phần sau để cập nhật số cổng:
{ "port": 5000 }
Điều này sẽ hoạt động như file cấu hình cho json-server
và nó sẽ đảm bảo server luôn chạy trên cổng được chỉ định trong đó.
Lưu và thoát khỏi file .
Để chạy server , hãy sử dụng lệnh sau:
- json-server --watch server/db.json
Thao tác này sẽ khởi động json-server
trên cổng 5000
. Nếu bạn chuyển đến http://localhost:5000/customers
trong trình duyệt của bạn , bạn sẽ thấy server hiển thị danh sách khách hàng của bạn .
Để hợp lý hóa quá trình chạy json-server
, bạn có thể cập nhật package.json
với một thuộc tính mới có tên là server
cho đối tượng scripts
như được hiển thị ở đây:
{ ... "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "server": "json-server --watch server/db.json" }, ... }
Lưu và thoát khỏi file .
Bây giờ bất cứ lúc nào bạn muốn khởi động json-server
, tất cả những gì bạn phải làm là chạy yarn server
từ terminal .
Bạn đã tạo một API REST đơn giản mà bạn sẽ sử dụng làm server back-end cho ứng dụng này. Bạn cũng đã tạo một đối tượng JSON của khách hàng sẽ được sử dụng làm dữ liệu mặc định cho API REST. Cuối cùng, bạn đã cấu hình một cổng thay thế cho server back-end do json-server
cung cấp. Tiếp theo, bạn sẽ xây dựng các thành phần có thể tái sử dụng cho ứng dụng của bạn .
Bước 3 - Tạo các thành phần có thể tái sử dụng
Trong phần này, bạn sẽ tạo các thành phần React cần thiết cho ứng dụng. Điều này sẽ bao gồm các thành phần để tạo, hiển thị và chỉnh sửa các chi tiết của một khách hàng cụ thể trong database tương ứng. Bạn cũng sẽ xây dựng một số giao diện TypeScript cho ứng dụng của bạn .
Để bắt đầu, hãy quay lại terminal nơi bạn có ứng dụng React đang chạy và dừng server phát triển bằng CTRL + C
Tiếp theo, chuyển đến folder ./src/
:
- cd ./src/
Sau đó, tạo một folder mới có tên là components
bên trong nó và chuyển vào folder mới:
- mkdir components
- cd components
Trong folder mới được tạo, hãy tạo một folder customer
và sau đó chuyển vào đó:
- mkdir customer
- cd customer
Bây giờ, hãy tạo hai file mới có tên Create.tsx
và Edit.tsx
:
- touch Create.tsx Edit.tsx
Các file này là các thành phần có thể tái sử dụng của React sẽ hiển thị các biểu mẫu và lưu giữ tất cả logic nghiệp vụ để tạo và chỉnh sửa các chi tiết của khách hàng tương ứng.
Mở file Create.tsx
trong editor của bạn và thêm mã sau:
import * as React from 'react'; import axios from 'axios'; import { RouteComponentProps, withRouter } from 'react-router-dom'; export interface IValues { first_name: string, last_name: string, email: string, phone: string, address: string, description: string, } export interface IFormState { [key: string]: any; values: IValues[]; submitSuccess: boolean; loading: boolean; }
Tại đây, bạn đã nhập React
, axios
và các thành phần bắt buộc khác cần thiết cho việc định tuyến từ gói React Router. Sau đó, bạn đã tạo hai giao diện mới có tên là IValues
và IFormState
. Các giao diện TypeScript giúp xác định loại giá trị cụ thể cần được chuyển cho một đối tượng và thực thi tính nhất quán trong toàn bộ ứng dụng. Điều này đảm bảo các lỗi ít có khả năng xuất hiện trong chương trình của bạn.
Tiếp theo, bạn sẽ xây dựng một thành phần Create
mở rộng React.Component
. Thêm mã sau vào file Create.tsx
ngay sau giao diện IFormState
:
... class Create extends React.Component<RouteComponentProps, IFormState> { constructor(props: RouteComponentProps) { super(props); this.state = { first_name: '', last_name: '', email: '', phone: '', address: '', description: '', values: [], loading: false, submitSuccess: false, } } } export default withRouter(Create)
Ở đây bạn đã xác định một thành phần React trong Typescript. Trong trường hợp này, thành phần lớp Create
chấp nhận các props
(viết tắt của “thuộc tính”) kiểu RouteComponentProps
và sử dụng trạng thái kiểu IFormState
. Sau đó, bên trong hàm tạo, bạn khởi tạo đối tượng state
và xác định tất cả các biến sẽ đại diện cho các giá trị được hiển thị cho một khách hàng.
Tiếp theo, thêm các phương thức này trong thành phần lớp Create
, chỉ sau hàm tạo. Bạn sẽ sử dụng các phương pháp này để xử lý biểu mẫu khách hàng và xử lý tất cả các thay đổi trong các trường đầu vào:
... values: [], loading: false, submitSuccess: false, } } private processFormSubmission = (e: React.FormEvent<HTMLFormElement>): void => { e.preventDefault(); this.setState({ loading: true }); const formData = { first_name: this.state.first_name, last_name: this.state.last_name, email: this.state.email, phone: this.state.phone, address: this.state.address, description: this.state.description, } this.setState({ submitSuccess: true, values: [...this.state.values, formData], loading: false }); axios.post(`http://localhost:5000/customers`, formData).then(data => [ setTimeout(() => { this.props.history.push('/'); }, 1500) ]); } private handleInputChanges = (e: React.FormEvent<HTMLInputElement>) => { e.preventDefault(); this.setState({ [e.currentTarget.name]: e.currentTarget.value, }) } ... export default withRouter(Create) ...
Phương thức processFormSubmission()
nhận thông tin chi tiết của khách hàng từ trạng thái ứng dụng và đăng nó vào database bằng cách sử dụng axios
. handleInputChanges()
sử dụng React.FormEvent
để lấy giá trị của tất cả các trường đầu vào và gọi this.setState()
để cập nhật trạng thái của ứng dụng.
Tiếp theo, thêm phương thức render()
trong thành phần lớp Create
ngay sau phương thức handleInputchanges()
. Phương thức render()
này sẽ hiển thị biểu mẫu để tạo khách hàng mới trong ứng dụng:
... public render() { const { submitSuccess, loading } = this.state; return ( <div> <div className={"col-md-12 form-wrapper"}> <h2> Create Post </h2> {!submitSuccess && ( <div className="alert alert-info" role="alert"> Fill the form below to create a new post </div> )} {submitSuccess && ( <div className="alert alert-info" role="alert"> The form was successfully submitted! </div> )} <form id={"create-post-form"} onSubmit={this.processFormSubmission} noValidate={true}> <div className="form-group col-md-12"> <label htmlFor="first_name"> First Name </label> <input type="text" id="first_name" onChange={(e) => this.handleInputChanges(e)} name="first_name" className="form-control" placeholder="Enter customer's first name" /> </div> <div className="form-group col-md-12"> <label htmlFor="last_name"> Last Name </label> <input type="text" id="last_name" onChange={(e) => this.handleInputChanges(e)} name="last_name" className="form-control" placeholder="Enter customer's last name" /> </div> <div className="form-group col-md-12"> <label htmlFor="email"> Email </label> <input type="email" id="email" onChange={(e) => this.handleInputChanges(e)} name="email" className="form-control" placeholder="Enter customer's email address" /> </div> <div className="form-group col-md-12"> <label htmlFor="phone"> Phone </label> <input type="text" id="phone" onChange={(e) => this.handleInputChanges(e)} name="phone" className="form-control" placeholder="Enter customer's phone number" /> </div> <div className="form-group col-md-12"> <label htmlFor="address"> Address </label> <input type="text" id="address" onChange={(e) => this.handleInputChanges(e)} name="address" className="form-control" placeholder="Enter customer's address" /> </div> <div className="form-group col-md-12"> <label htmlFor="description"> Description </label> <input type="text" id="description" onChange={(e) => this.handleInputChanges(e)} name="description" className="form-control" placeholder="Enter Description" /> </div> <div className="form-group col-md-4 pull-right"> <button className="btn btn-success" type="submit"> Create Customer </button> {loading && <span className="fa fa-circle-o-notch fa-spin" /> } </div> </form> </div> </div> ) } ...
Tại đây, bạn đã tạo một biểu mẫu với các trường đầu vào để lưu giữ các giá trị của first_name
, last_name
, email
, phone
, address
và description
của khách hàng. Mỗi trường đầu vào có một phương thức handleInputChanges()
chạy trên mỗi lần gõ phím, cập nhật state
React với giá trị mà nó nhận được từ trường đầu vào. Hơn nữa, tùy thuộc vào trạng thái của ứng dụng, một biến boolean có tên là submitSuccess
sẽ kiểm soát thông báo mà ứng dụng sẽ hiển thị trước và sau khi tạo khách hàng mới.
Bạn có thể xem mã hoàn chỉnh cho file này trong kho lưu trữ GitHub này.
Lưu và thoát khỏi Create.tsx
.
Đến đây bạn đã thêm logic thích hợp vào file Create
thành phần cho ứng dụng, bạn sẽ tiến hành thêm nội dung cho file thành phần Edit
.
Mở file Edit.tsx
của bạn trong folder customer
và bắt đầu bằng cách thêm nội dung sau để nhập React
, axios
và cũng xác định giao diện TypeScript:
import * as React from 'react'; import { RouteComponentProps, withRouter } from 'react-router-dom'; import axios from 'axios'; export interface IValues { [key: string]: any; } export interface IFormState { id: number, customer: any; values: IValues[]; submitSuccess: boolean; loading: boolean; }
Tương tự như vậy với Create
thành phần, bạn nhập các module cần thiết và tạo IValues
và IFormState
giao diện tương ứng. Giao diện IValues
xác định kiểu dữ liệu cho các giá trị của trường đầu vào, trong khi bạn sẽ sử dụng IFormState
để khai báo kiểu mong đợi cho đối tượng trạng thái của ứng dụng.
Tiếp theo, tạo thành phần lớp EditCustomer
trực tiếp sau khối giao diện IFormState
như được hiển thị ở đây:
... class EditCustomer extends React.Component<RouteComponentProps<any>, IFormState> { constructor(props: RouteComponentProps) { super(props); this.state = { id: this.props.match.params.id, customer: {}, values: [], loading: false, submitSuccess: false, } } } export default withRouter(EditCustomer)
Thành phần này lấy RouteComponentProps<any>
và một giao diện của IFormState
làm tham số. Bạn sử dụng việc bổ sung <any>
vào RouteComponentProps
bởi vì khi nào React Router phân tích cú pháp các tham số đường dẫn, nó không thực hiện bất kỳ chuyển đổi kiểu nào để xác định loại dữ liệu là number
hay string
. Vì bạn đang mong đợi một tham số cho uniqueId
của một khách hàng, nên sử dụng any
sẽ an toàn hơn.
Bây giờ hãy thêm các phương thức sau vào thành phần:
... public componentDidMount(): void { axios.get(`http://localhost:5000/customers/${this.state.id}`).then(data => { this.setState({ customer: data.data }); }) } private processFormSubmission = async (e: React.FormEvent<HTMLFormElement>): Promise<void> => { e.preventDefault(); this.setState({ loading: true }); axios.patch(`http://localhost:5000/customers/${this.state.id}`, this.state.values).then(data => { this.setState({ submitSuccess: true, loading: false }) setTimeout(() => { this.props.history.push('/'); }, 1500) }) } private setValues = (values: IValues) => { this.setState({ values: { ...this.state.values, ...values } }); } private handleInputChanges = (e: React.FormEvent<HTMLInputElement>) => { e.preventDefault(); this.setValues({ [e.currentTarget.id]: e.currentTarget.value }) } ... } export default withRouter(EditCustomer)
Đầu tiên, bạn thêm một phương thức componentDidMount()
, là một phương thức vòng đời đang được gọi khi thành phần được tạo. Phương thức này lấy id
thu được từ tham số tuyến đường để xác định một khách hàng cụ thể làm tham số, sử dụng nó để lấy thông tin chi tiết của họ từ database và sau đó điền vào biểu mẫu với nó. Hơn nữa, bạn thêm các phương thức để xử lý gửi biểu mẫu và xử lý các thay đổi được thực hiện đối với giá trị của các trường đầu vào.
Cuối cùng, thêm phương thức render()
cho thành phần Edit
:
... public render() { const { submitSuccess, loading } = this.state; return ( <div className="App"> {this.state.customer && <div> < h1 > Customer List Management App</h1> <p> Built with React.js and TypeScript </p> <div> <div className={"col-md-12 form-wrapper"}> <h2> Edit Customer </h2> {submitSuccess && ( <div className="alert alert-info" role="alert"> Customer's details has been edited successfully </div> )} <form id={"create-post-form"} onSubmit={this.processFormSubmission} noValidate={true}> <div className="form-group col-md-12"> <label htmlFor="first_name"> First Name </label> <input type="text" id="first_name" defaultValue={this.state.customer.first_name} onChange={(e) => this.handleInputChanges(e)} name="first_name" className="form-control" placeholder="Enter customer's first name" /> </div> <div className="form-group col-md-12"> <label htmlFor="last_name"> Last Name </label> <input type="text" id="last_name" defaultValue={this.state.customer.last_name} onChange={(e) => this.handleInputChanges(e)} name="last_name" className="form-control" placeholder="Enter customer's last name" /> </div> <div className="form-group col-md-12"> <label htmlFor="email"> Email </label> <input type="email" id="email" defaultValue={this.state.customer.email} onChange={(e) => this.handleInputChanges(e)} name="email" className="form-control" placeholder="Enter customer's email address" /> </div> <div className="form-group col-md-12"> <label htmlFor="phone"> Phone </label> <input type="text" id="phone" defaultValue={this.state.customer.phone} onChange={(e) => this.handleInputChanges(e)} name="phone" className="form-control" placeholder="Enter customer's phone number" /> </div> <div className="form-group col-md-12"> <label htmlFor="address"> Address </label> <input type="text" id="address" defaultValue={this.state.customer.address} onChange={(e) => this.handleInputChanges(e)} name="address" className="form-control" placeholder="Enter customer's address" /> </div> <div className="form-group col-md-12"> <label htmlFor="description"> Description </label> <input type="text" id="description" defaultValue={this.state.customer.description} onChange={(e) => this.handleInputChanges(e)} name="description" className="form-control" placeholder="Enter Description" /> </div> <div className="form-group col-md-4 pull-right"> <button className="btn btn-success" type="submit"> Edit Customer </button> {loading && <span className="fa fa-circle-o-notch fa-spin" /> } </div> </form> </div> </div> </div> } </div> ) } ...
Tại đây, bạn đã tạo một biểu mẫu để chỉnh sửa thông tin chi tiết của một khách hàng cụ thể, rồi điền vào các trường đầu vào trong biểu mẫu đó với thông tin chi tiết của khách hàng mà trạng thái ứng dụng của bạn có được. Tương tự với thành phần Create
, các thay đổi được thực hiện đối với tất cả các trường đầu vào sẽ được xử lý bởi phương thức handleInputChanges()
.
Bạn có thể xem mã hoàn chỉnh cho file này trong kho lưu trữ GitHub này.
Lưu và thoát khỏi Edit.tsx
.
Để xem danh sách đầy đủ các khách hàng được tạo trong ứng dụng, bạn sẽ tạo một thành phần mới trong folder ./src/components
và đặt tên là Home.tsx
:
- cd ./src/components
- nano Home.tsx
Thêm nội dung sau:
import * as React from 'react'; import { Link, RouteComponentProps } from 'react-router-dom'; import axios from 'axios'; interface IState { customers: any[]; } export default class Home extends React.Component<RouteComponentProps, IState> { constructor(props: RouteComponentProps) { super(props); this.state = { customers: [] } } public componentDidMount(): void { axios.get(`http://localhost:5000/customers`).then(data => { this.setState({ customers: data.data }) }) } public deleteCustomer(id: number) { axios.delete(`http://localhost:5000/customers/${id}`).then(data => { const index = this.state.customers.findIndex(customer => customer.id === id); this.state.customers.splice(index, 1); this.props.history.push('/'); }) } }
Tại đây, bạn đã nhập React
, axios
và các thành phần bắt buộc khác từ React Router. Bạn đã tạo hai phương thức mới trong thành phần Home
:
-
componentDidMount()
: Ứng dụng gọi phương thức này ngay lập tức sau khi một thành phần được mount . Trách nhiệm của nó ở đây là lấy danh sách khách hàng và cập nhật trang chủ với nó. -
deleteCustomer()
: Phương thức này sẽ chấp nhận mộtid
làm tham số và sẽ xóa thông tin chi tiết của khách hàng được xác định vớiid
đó khỏi database .
Bây giờ thêm phương thức render()
để hiển thị bảng chứa danh sách khách hàng cho thành phần Home
:
... public render() { const customers = this.state.customers; return ( <div> {customers.length === 0 && ( <div className="text-center"> <h2>No customer found at the moment</h2> </div> )} <div className="container"> <div className="row"> <table className="table table-bordered"> <thead className="thead-light"> <tr> <th scope="col">Firstname</th> <th scope="col">Lastname</th> <th scope="col">Email</th> <th scope="col">Phone</th> <th scope="col">Address</th> <th scope="col">Description</th> <th scope="col">Actions</th> </tr> </thead> <tbody> {customers && customers.map(customer => <tr key={customer.id}> <td>{customer.first_name}</td> <td>{customer.last_name}</td> <td>{customer.email}</td> <td>{customer.phone}</td> <td>{customer.address}</td> <td>{customer.description}</td> <td> <div className="d-flex justify-content-between align-items-center"> <div className="btn-group" style={{ marginBottom: "20px" }}> <Link to={`edit/${customer.id}`} className="btn btn-sm btn-outline-secondary">Edit Customer </Link> <button className="btn btn-sm btn-outline-secondary" onClick={() => this.deleteCustomer(customer.id)}>Delete Customer</button> </div> </div> </td> </tr> )} </tbody> </table> </div> </div> </div> ) } ...
Trong khối mã này, bạn truy xuất danh sách khách hàng từ trạng thái của ứng dụng dưới dạng một mảng, lặp qua nó và hiển thị nó trong bảng HTML. Bạn cũng thêm tham số customer.id
, tham số này sử dụng để xác định và xóa thông tin chi tiết của một khách hàng cụ thể khỏi danh sách.
Lưu và thoát khỏi Home.tsx
.
Bạn đã áp dụng nguyên tắc nhập tĩnh cho tất cả các thành phần được tạo bằng ứng dụng này bằng cách xác định kiểu cho các thành phần và đạo cụ thông qua việc sử dụng các giao diện. Đây là một trong những cách tốt nhất để sử dụng TypeScript cho một ứng dụng React.
Với điều này, bạn đã hoàn thành việc tạo tất cả các thành phần có thể sử dụng lại được yêu cầu cho ứng dụng. Như vậy, bạn có thể cập nhật thành phần ứng dụng bằng các liên kết đến tất cả các thành phần mà bạn đã tạo cho đến nay.
Bước 4 - Cài đặt định tuyến và cập nhật điểm nhập của ứng dụng
Trong bước này, bạn sẽ nhập các thành phần cần thiết từ gói Bộ định tuyến React và cấu hình thành phần App
để hiển thị các thành phần khác nhau tùy thuộc vào tuyến được tải. Điều này sẽ cho phép bạn chuyển qua các trang khác nhau của ứng dụng. Khi user truy cập một tuyến đường, ví dụ /create
, Bộ định tuyến React sẽ sử dụng đường dẫn được chỉ định để hiển thị nội dung và logic bên trong thành phần thích hợp được xác định để xử lý tuyến đường đó.
Điều hướng đến ./src/App.tsx
:
- nano App.tsx
Sau đó thay thế nội dung của nó bằng nội dung sau:
import * as React from 'react'; import './App.css'; import { Switch, Route, withRouter, RouteComponentProps, Link } from 'react-router-dom'; import Home from './components/Home'; import Create from './components/customer/Create'; import EditCustomer from './components/customer/Edit'; class App extends React.Component<RouteComponentProps<any>> { public render() { return ( <div> <nav> <ul> <li> <Link to={'/'}> Home </Link> </li> <li> <Link to={'/create'}> Create Customer </Link> </li> </ul> </nav> <Switch> <Route path={'/'} exact component={Home} /> <Route path={'/create'} exact component={Create} /> <Route path={'/edit/:id'} exact component={EditCustomer} /> </Switch> </div> ); } } export default withRouter(App);
Bạn đã nhập tất cả các thành phần cần thiết từ gói Bộ định tuyến React và bạn cũng nhập các thành phần có thể sử dụng lại để tạo, chỉnh sửa và xem chi tiết của khách hàng.
Lưu và thoát khỏi App.tsx
.
Tệp ./src/index.tsx
là điểm nhập cho ứng dụng này và hiển thị ứng dụng. Mở file này và nhập Bộ định tuyến React vào đó, sau đó bọc thành phần App
bên trong BrowserRouter
:
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import { BrowserRouter } from 'react-router-dom'; import * as serviceWorker from './serviceWorker'; ReactDOM.render( <BrowserRouter> <App /> </BrowserRouter> , document.getElementById('root') ); serviceWorker.unregister();
React Router sử dụng thành phần BrowserRouter
để làm cho ứng dụng của bạn nhận biết được chuyển , chẳng hạn như lịch sử và đường dẫn hiện tại.
Khi bạn đã hoàn tất việc chỉnh sửa Index.tsx
, hãy lưu và thoát.
Cuối cùng, bạn sẽ sử dụng Bootstrap để thêm một số kiểu cho ứng dụng của bạn . Bootstrap là một khuôn khổ HTML, CSS và JavaScript phổ biến để phát triển các dự án đáp ứng, ưu tiên thiết bị di động trên web. Nó cho phép các nhà phát triển xây dựng một giao diện user hấp dẫn mà không cần phải viết quá nhiều CSS. Nó đi kèm với một hệ thống lưới đáp ứng cung cấp cho một trang web một giao diện hoàn chỉnh, hoạt động trên tất cả các thiết bị.
Để bao gồm Bootstrap và tạo kiểu cho ứng dụng của bạn, hãy thay thế nội dung của ./src/App.css
bằng nội dung sau:
@import 'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css'; .form-wrapper { width: 500px; margin: 0 auto; } .App { text-align: center; margin-top: 30px; } nav { width: 300px; margin: 0 auto; background: #282c34; height: 70px; line-height: 70px; } nav ul li { display: inline; list-style-type: none; text-align: center; padding: 30px; } nav ul li a { margin: 50px 0; font-weight: bold; color: white; text-decoration: none; } nav ul li a:hover { color: white; text-decoration: none; } table { margin-top: 50px; } .App-link { color: #61dafb; } @keyframes App-logo-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
Bạn đã sử dụng Bootstrap tại đây để nâng cao giao diện của ứng dụng bằng cách tạo cho nó một bố cục, kiểu và màu mặc định. Bạn cũng đã thêm một số kiểu tùy chỉnh, đặc biệt là vào thanh chuyển .
Lưu và thoát khỏi App.css
.
Trong phần này, bạn đã cấu hình React Router để hiển thị thành phần thích hợp tùy thuộc vào tuyến đường mà user truy cập và cũng thêm một số kiểu để làm cho ứng dụng hấp dẫn hơn với user . Tiếp theo, bạn sẽ kiểm tra tất cả các chức năng được triển khai cho ứng dụng.
Bước 5 - Chạy ứng dụng của bạn
Đến đây bạn đã cài đặt giao diện user của ứng dụng này với React và TypeScript bằng cách tạo một số thành phần có thể tái sử dụng và cũng đã xây dựng API REST với json-server
, bạn có thể chạy ứng dụng của bạn .
Điều hướng trở lại folder root của dự án:
- cd ~/typescript-react-app
Tiếp theo, chạy lệnh sau để khởi động ứng dụng của bạn:
- yarn start
Lưu ý: Đảm bảo rằng server của bạn vẫn đang chạy trong cửa sổ terminal khác. Nếu không, hãy bắt đầu với: yarn server
.
Điều hướng đến http://localhost:3000
để xem ứng dụng từ trình duyệt của bạn. Sau đó tiến hành bấm vào nút Tạo và điền thông tin chi tiết của một khách hàng.
Sau khi nhập các giá trị thích hợp vào các trường đầu vào, hãy nhấp vào nút Tạo khách hàng để gửi biểu mẫu. Ứng dụng sẽ chuyển hướng bạn trở lại trang chủ sau khi bạn hoàn tất việc tạo khách hàng mới.
Nhấp vào nút Chỉnh sửa khách hàng cho bất kỳ hàng nào và bạn sẽ được dẫn đến trang lưu trữ chức năng chỉnh sửa cho khách hàng tương ứng trên hàng đó.
Chỉnh sửa thông tin chi tiết của khách hàng và sau đó nhấp vào Chỉnh sửa khách hàng để cập nhật thông tin chi tiết của khách hàng.
Bạn đã chạy ứng dụng của bạn đảm bảo tất cả các thành phần đang hoạt động. Sử dụng các trang khác nhau trong ứng dụng của bạn, bạn đã tạo và chỉnh sửa mục nhập của khách hàng.
Kết luận
Trong hướng dẫn này, bạn đã xây dựng một ứng dụng quản lý danh sách khách hàng với React và TypeScript . Quy trình trong hướng dẫn này khác với việc sử dụng JavaScript như cách thông thường để cấu trúc và xây dựng ứng dụng với React. Bạn đã tận dụng những lợi ích của việc sử dụng TypeScript để hoàn thành hướng dẫn tập trung vào giao diện user này.
Để tiếp tục phát triển dự án này, bạn có thể di chuyển server back-end giả của bạn sang công nghệ back-end sẵn sàng production như Express hoặc Nest.js. Hơn nữa, bạn có thể mở rộng những gì bạn đã xây dựng trong hướng dẫn này bằng cách thêm nhiều tính năng hơn như xác thực và ủy quyền với các công cụ khác nhau như thư viện xác thực Passport.js .
Bạn có thể tìm thấy mã nguồn hoàn chỉnh cho dự án trên GitHub .
Các tin liên quan