Vậy bạn đã quyết định học Reactjs. Xin chúc mừng! Cẩm nang hướng dẫn ReactJS này nhằm giúp bạn tìm hiểu bốn khía cạnh cơ bản của thư viện chúng tôi vô cùng mạnh mẽ này trong lập trình front end. Chúng ta sẽ xây dựng một ứng dụng chúng tôi rất đơn giản cho phép người dùng nhập cụm từ tìm kiếm và truy xuất danh sách các bức ảnh phù hợp với thuật ngữ này từ Unsplash API. Chúng ta hãy bắt đầu.
React JS Components
React JS Component là các block xây dựng nên mọi ứng dụng React. Một component có thể được sử dụng riêng hoặc được kết hợp với các component khác để tạo ra các component lớn hơn. Điều quan trọng, các component này là động: chúng cung cấp một template, sẽ được điền vào bằng dữ liệu biến. Mục đích chính của một component React là tạo ra một số JSX từ template này, và sẽ biên dịch sang HTML và được hiển thị trên DOM.
Class-based component, mặt khác, cần phải nhận thức được những gì người dùng đang làm. Ví dụ: nếu người dùng nhấp hoặc gõ trên trang, component cần phải respond lại theo một cách nào đó. Nói một cách đơn giản nhất, một Class-based component cần phải nhận thức được trạng thái.
Các Class-based component có một số method nhằm kích hoạt vào các điểm khác nhau trong quá trình instantiation và rendering, bao gồm constructor, render, và componentDidMount. Yêu cầu duy nhất của Class-based component là render method, vì đây là method trong đó component trả về JSX, mặc dù trạng thái thường (nhưng không phải luôn luôn) được đặt bên trong constructor method. Nếu bạn sử dụng constructor method, bạn phải gọi super ở phần đầu. Cuối cùng, nếu bạn dự định fetch data để sử dụng trong ứng dụng của mình, việc này phải được thực hiện bên trong componentDidMount, sẽ kích hoạt sau khi render.
Ứng dụng tìm kiếm ảnh của chúng ta sẽ có bốn component: Appcomponent, sẽ chứa các component khác, searchBarcomponent, PhotoList component và PhotoListItem component. JSX mà các component PhotoList và PhotoListItem sẽ hiển thị từ Unsplash API, sẽ phụ thuộc vào từ khóa người dùng nhập vào SearchBar. Như vậy, App component của chúng ta, vì là container, sẽ là component chịu trách nhiệm theo dõi cụm từ tìm kiếm đó và tìm dữ liệu tương ứng. Điều này có nghĩa App sẽ là một class-based component và các component khác sẽ là functional.
JSX
Tôi đã đề cập ở trên rằng nhiệm vụ quan trọng nhất của các component là tạo ra một số JSX dựa trên template, sau đó sẽ được dịch sang HTML. Nhưng JSX là gì?
Theo React Docs, JSX là một syntax extension cho JavaScript. Nó có vẻ rất giống với HTML, nhưng với một số khác biệt chính. Ví dụ: bạn có thể bao gồm một vanilla JavaScript expression bên trong JSX bằng cách wrap nó trong dấu ngoặc nhọn:
Ngoài ra, các HTML element có thể có một Class, nhưng các element trong JSX có một “className”. Chúng có ý nghĩa giống nhau và CSS sẽ respond với className tương tự với class trong HTML. Sự khác biệt này được tạo ra bởi vì class là một từ dành riêng trong ES6 và vì JSX thực sự là JavaScript, nên nó không thể sử dụng lại từ này.
Mặc dù JSX trông cực kỳ giống với HTML, nhưng nó phải được dịch thành vanilla JavaScript bằng Babel để trình duyệt có thể diễn dịch nó. Ví dụ: khi Babel nhìn thấy JSX bên dưới:
… nó sẽ chuyển thành function bên dưới, và trả về kết quả của React.createElement(). React.createElement() nhận hai argument: tag name của element được tạo và nội dung bên trong tag.
Bạnkhông cần phải viết JSX trong các component React; thay vào đó, bạn có thể viết lại React.createElement() nhiều lần và code của bạn sẽ không cần phải được dịch ra. Nhưng với tư cách là lập trình viên, chúng ta muốn ngắn gọn và viết JavaScript vanilla này bên trong các component sẽ làm nó nhanh chóng trở nên lộn xộn, đặc biệt là khi bạn có các JSX tag lồng vào nhau.
Tuy nhiên, có một cảnh báo khi sử dụng JSX. Hãy xem điều gì xảy ra nếu chúng ta cố gắng để component hiển thị hai sibling JSX element:
Lỗi này phát sinh bởi vì, khi Babel dịch JSX tag, nó biến thành một function trả về kết quả của React.createElement(). Bởi vì từ khóa “Return” cơ bản là một điểm dừng – nghĩa là, một điểm mà tại đó code dừng chạy – nó không thể có hai câu lệnh return trong một component. Vì vậy, để hiển thị các sibling element, chúng phải được lồng bên trong một parent div, như vậy:
Một nguyên tắc đối với JSX: khi không chắc chắn, hãy render mọi thứ bên trong một single div (hoặc Fragment).
State
State có lẽ là khái niệm khó hiểu nhất khi học ReactJs, nhưng bạn cần phải hiểu nó nhằm ứng dụng tất cả các tính năng tuyệt vời của React cho các dự án của bạn. Nói một cách đơn giản nhất, state là một đối tượng JavaScript ghi lại và phản ứng với các user event. Mỗi class-based component có state object riêng và bất cứ khi nào state bị thay đổi, component đó cùng với tất cả các phần tử con của nó sẽ được hiển thị lại.
Initial state chỉ có thể được đặt trong constructor method của component, được gọi là instantiation. Vì App component của chúng ta là class-based, chúng tôi sẽ tuân theo quy tắc đó:
Đây là lần duy nhất bạn nên đặt this.state bằng với một object. Chẳng hạn, nếu người dùng tương tác với component và bạn cần cập nhật nó để phản ánh hành động của họ, bạn phải sử dụng một syntax khác:
this .setState ({term: ‘sunsets’})
Một trong những phần khó nhất để làm chủ state là quyết định component nào trong ứng dụng của bạn nên có state. Để làm như vậy, trước tiên hãy đánh giá component nào của bạn phụ thuộc vào dữ liệu sẽ thay đổi theo thời gian. Component có state nên là parent của tất cả các component này, bởi vì các component con sẽ có quyền truy cập vào dữ liệu thay đổi thông qua props object của chúng.
Nhưng thế nào là một props object?
Props
Tôi đã đề cập trước đó rằng bất cứ khi nào một component state thay đổi, component đó và tất cả các phần tử con của nó sẽ render lại. Tại sao cần phải cho một component children render lại khi parent component state thay đổi? Câu trả lời là: props.
Chúng ta hãy chia nhỏ việc này ra. Khi app component render lần đầu tiên, componentDidMount method của nó sẽ chạy. Vì người dùng chưa gõ bất kỳ thứ gì vào thanh tìm kiếm, nên từ khóa trong state bị trống. Như vậy, component này fetch các ảnh từ API khớp với từ khóa mặc định “coding”. Sau đó, nó sẽ đặt dữ liệu được trả về cho từ khóa “photos” bên trong state của nó và hiển thị lại. Trong quá trình re-rendering, nó chuyển a) changeSearchTermState method và từ khóa xuống SearchBar dưới dạng props và b) các array của “photos” xuống PhotoList dưới dạng props.
Bây giờ, chúng ta hãy nhìn về SearchBar:
Chúng ta đã khai báo SearchBar component là một biến const, chứ không phải là một class, có nghĩa là nó là một functional component thuần túy. Điều này có vẻ trái ngược, vì SearchBar cần theo dõi các user event. Nhưng vì tất cả các component khác, bao gồm cả App, phụ thuộc vào bất cứ điều gì người dùng nhập vào SearchBar, chúng tôi nâng state của nó lên App (với từ khóa bên trong App’s state). Sau đó, chúng ta có thể thay đổi giá trị của từ khóa bên trong App’s state với changeSearchTermState callback bên trong của SearchBar props. Mỗi khi người dùng nhập vào, changeSearchTermState method của App sẽ kích hoạt, thiết lập lại các từ khóa bên trong App’s state, từ đó kích hoạt re-render và cuối cùng là gọi đến Unsplash API.
Bây giờ, chúng ta hãy xem đến PhotoList. Như tôi đã đề cập, PhotoList nhận được array ảnh bên trong App’s state dưới dạng props. Nhưng nó làm gì với dữ liệu đó? Chúng ta hãy xem:
PhotoList.js
Props object của functional component này chứa tất cả các ảnh được truy xuất từ Unsplash API phù hợp với từ khóa tìm kiếm của người dùng. Bây giờ, nó sẽ đi qua một loạt khóa “photos” bên trong props object, từ đó trỏ đến một array ảnh và tạo một photoListItem riêng lẻ từ mỗi element trong array đó. Và chúng ta thậm chí còn chuyển cho PhotoListItem đó một prop riêng của nó – một URL, xuất phát từ App state. Tất cả những gì còn lại là dành cho PhotoListItem để render JSX cho DOM. Vì mỗi PhotoListItem có một URL bên trong các props của nó, chúng ta có thể đặt URL đó làm thuộc tính src của thẻ img bên trong div, như sau:
PhotoListItem.js
Và bây giờ, công việc đã hoàn thành! Nhờ vào sức mạnh của props, chúng ta có thể nhìn thấy hình ảnh trên DOM một cách tuyệt vời.
Sản phẩm đã hoàn thành trên máy chủ cục bộ
Kết luận
Mặc dù hướng dẫn này không đầy đủ, nhưng mục tiêu của nó là giới thiệu cho bạn về những gì tôi coi là bốn trụ cột chính của React. Tôi đã thêm bản repo hoàn chỉnh vào GitHub, bạn cứ thoải mái download nó xuống và xem xét kỹ hơn. Bạn chỉ cần phải tạo khóa API riêng bạn cho Unsplash.
Bạn muốn trở thành lập trình viên chuyên nghiệp trong thời gian ngắn nhất? Bạn muốn có việc làm IT mức lương khủng sau khoá học? Hãy đăng ký các khoá học lập trình online và offline tại Nordic Coder – Trung tâm dạy lập trình uy tín và chuyên nghiệp. Ngoài ra, Nordic Coder còn là cầu nối nghề nghiệp IT giữa học viên và với các công ty công nghệ hàng đầu Việt Nam sau các khoá học lập trình.