Component đầu tiên của bạn

Component là một trong những khái niệm cơ bản của React. Chúng là nền tảng bạn dựa vào để xây dựng giao diện (UI) và điều đó khiến chúng là một khởi đầu hoàn hảo để bắt đầu hành trình React của bạn!

You will learn

  • Một component là gì
  • Vai trò của component trong một ứng dụng React
  • Cách để viết React component đầu tiên của bạn

Component: Những viên gạch để xây dựng UI

Ở Web, HTML cho chúng ta tạo ra các tài liệu với cấu trúc phong phú sử dụng các thẻ có sẵn như <h1><li>:

<article>
<h1>My First Component</h1>
<ol>
<li>Components: UI Building Blocks</li>
<li>Defining a Component</li>
<li>Using a Component</li>
</ol>
</article>

Phần markup này bao gồm bài viết này <article>, tiêu đề của nó <h1>, và một bảng mục lục (tóm tắt) được biểu diễn bằng một danh sách có thứ tự <ol>. Markup như thế này, kết hợp với CSS để thêm các styles, và JavaScript để tạo tính tương tác, nằm phía sau sidebar, ảnh đại diện (avatar), modal, dropdown — mỗi phần của UI bạn thấy trên Web.

React cho phép bạn kết hợp markup, CSS, và JavaScript để tạo nên các “component” tự làm, những phần tử UI có thể tái sử dụng cho ứng dụng của bạn. Bảng mục lục bạn thấy ở trên có thể được chuyển thành một component <TableOfContents /> mà bạn có thể render trên mọi trang. Phía sau cánh gà, nó vẫn sử dụng các thẻ HTML như <article>, <h1>, v.v.

Giống như với các thẻ HTML, bạn có thể tạo, sắp xếp và lồng các component để thiết kế nên các trang hoàn chỉnh. Ví dụ, trang tài liệu bạn đang đọc được tạo từ các React component như:

<PageLayout>
<NavigationHeader>
<SearchBar />
<Link to="/docs">Docs</Link>
</NavigationHeader>
<Sidebar />
<PageContent>
<TableOfContents />
<DocumentationText />
</PageContent>
</PageLayout>

Khi mà dự án của bạn phát triển, bạn sẽ nhận thấy rất nhiều các thiết kế của bạn có thể được xây dựng bằng cách tái sử dụng các component bạn đã viết, từ đó đẩy nhanh tốc độ phát triển. Mục lục của chúng tôi ở trên có thể được thêm vào bất cứ màn hình nào với <TableOfContents />! Bạn thậm chí còn có thể bắt đầu dự án của mình với hàng ngàn các component được chia sẻ bởi cộng đồng mã nguồn mở React như Chakra UIMaterial UI.

Định nghĩa một component

Theo truyền thống, khi tạo ra các trang web, các nhà phát triển web markup nội dung của họ và sau đó thêm khả năng tương tác bằng cách sử dụng thêm JavaScript. Cách này hoạt động tốt khi các tương tác vẫn còn là một thứ “có thì tốt” ở web. Bây giờ thì điều đó được kỳ vọng là sẵn có ở rất nhiều trang và mọi ứng dụng. React đặt tính tương tác lên đầu trong khi vẫn sử dụng các công nghệ tương tự: một React component là một hàm JavaScript mà bạn có thể dùng markup. Đây là một ví dụ (bạn có thể chỉnh sửa ví dụ bên dưới):

export default function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3Am.jpg"
      alt="Katherine Johnson"
    />
  )
}

Và đây là cách để xây dựng một component:

Bước 1: Xuất (Export) component

Tiền tố export default là một cú pháp JavaScript tiêu chuẩn (không cụ thể cho React). Nó cho phép bạn đánh dấu hàm chính của một file để bạn có thể nhập (import) nó từ những file khác. (Thêm thông tin về importing ở trong Import và Export các component!)

Bước 2: Định nghĩa hàm

Với function Profile() { } bạn định nghĩa một hàm JavaScript với tên là Profile.

Pitfall

React component là những hàm JavaScript bình thường, tuy nhiên tên của chúng phải bắt đầu bằng một chữ cái in hoa. Nếu không, chúng sẽ không hoạt động!

Bước 3: Thêm markup

Component trả về một thẻ <img /> với thuộc tính srcalt. <img /> được viết như HTML, nhưng chúng thật ra là JavaScript ở phía sau hậu trường! Cú pháp này được gọi là JSX, và nó cho phép bạn nhúng markup vào trong JavaScript.

Câu lệnh return có thể được viết hết ở trong một dòng, như trong component này:

return <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />;

Nhưng nếu markup của bạn không ở cùng một dòng với từ khóa return, bạn sẽ phải bao nó ở trong một cặp dấu ngoặc:

return (
<div>
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
</div>
);

Pitfall

Nếu không có cặp ngoặc, bất kỳ code nào ở sau return sẽ bị bỏ qua!

Sử dụng một component

Giờ thì bạn đã định nghĩa component Profile, bạn có thể lồng nó bên trong các component khác. Ví dụ, bạn có thể export một component Gallery sử dụng nhiều component Profile bên trong nó:

function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3As.jpg"
      alt="Katherine Johnson"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

Những gì mà trình duyệt nhìn thấy

Chú ý đến sự khác biệt về chữ hoa/chữ thường:

  • <section> viết thường, vì vậy React biết rằng chúng ta đang nói đến một thẻ HTML.
  • <Profile /> bắt đầu bằng chữ hoa, vì vậy React biết rằng chúng ta muốn sử dụng một component của chúng ta có tên là Profile.

Profile thì lại chứa nhiều HTML hơn nữa: <img />. Cuối cùng, đây là những gì mà trình duyệt nhìn thấy:

<section>
<h1>Amazing scientists</h1>
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
</section>

Lồng và sắp xếp các component

Component là các hàm JavaScript bình thường, nên bạn có thể có nhiều component ở trong cùng một file. Điều này tiện lợi khi các component vẫn còn nhỏ và liên quan đến nhau một cách chặt chẽ. Nếu file này càng ngày càng lớn, bạn luôn có thể dời Profile ra một file riêng. Bạn sẽ học cách làm điều này trong Import và Export các component

Bởi vì các component Profile được render bên trong Gallery—thậm chí nhiều lần!—chúng ta có thể nói rằng Gallery là một component cha (parent component), render mỗi Profile như một “con” (child). Đây là phần kỳ diệu của React: bạn có thể định nghĩa component một lần và sử dụng nó ở khắp các nơi và với số lần tùy thích.

Pitfall

Component có thể render các component khác, nhưng bạn không bao giờ được lồng các định nghĩa của chúng:

export default function Gallery() {
// 🔴 Never define a component inside another component!
function Profile() {
// ...
}
// ...
}

Phần code ở trên chạy rất chậm và gây ra bug Thay vào đó, hãy định nghĩa component ở đầu file:

export default function Gallery() {
// ...
}

// ✅ Declare components at the top level
function Profile() {
// ...
}

Khi mà một component con cần dữ liệu từ cha, hãy truyền nó qua props thay vì lồng các định nghĩa.

Deep Dive

Sử dụng Component từ đầu đến cuối

Ứng dụng React của bạn bắt đầu từ một component “gốc” (root). Thường thì component này được tạo ra tự động khi mà bạn bắt đầu một dự án mới. Ví dụ, nếu bạn dùng CodeSandbox hay Create React App, component gốc sẽ được định nghĩa ở src/App.js. Nếu bạn sử dụng framework Next.js, component gốc sẽ được định nghĩa ở pages/index.js. Trong những ví dụ này, bạn đã export các component gốc.

Hầu hết các ứng dụng React đều sử dụng component từ đầu đến cuối. Điều này có nghĩa là bạn không chỉ sử dụng component cho những phần có thể tái sử dụng như các nút (button) mà còn cho các phần lớn hơn như sidebar, các danh sách và đích đến cuối, các trang hoàn chỉnh! Component là một cách tiện lợi để tổ chức code UI và markup, ngay cả khi một số chúng chỉ được sử dụng một lần.

Các framwork React nâng điều này lên một tầm cao mới. Thay vì chỉ sử dụng một trang HTML rỗng và để React “điều khiển” việc quản lý trang với JavaScript, chúng cũng tạo ra HTML tự động từ các React component của bạn. Điều này khiến cho ứng dụng của bạn có thể hiển thị một số nội dung trước khi code JavaScript chạy.

Tuy vậy, rất nhiều website chỉ dùng React để thêm tương tác cho các trang HTML đã có sẵn. Họ có rất nhiều các root component thay vì một cái cho cả trang. Bạn có thể dùng nhiều hoặc ít React tùy thích.

Recap

Bạn vừa có được một cái nhìn đầu tiên về React! Hãy tóm tắt lại một số điểm quan trọng.

  • React cho bạn tạo ra các component, các thành phần UI có thể tái sử dụng cho ứng dụng của bạn.

  • Ở trong ứng dụng React, mỗi phần của UI là một component.

  • React component là các hàm JavaScript ngoại trừ việc:

    1. Tên của chúng luôn bắt đầu bằng chữ cái viết hoa.
    2. Chúng trả về JSX markup.

Challenge 1 of 4:
Export component

Phần sandbox này không chạy vì root component chưa được export:

function Profile() {
  return (
    <img
      src="https://i.imgur.com/lICfvbD.jpg"
      alt="Aklilu Lemma"
    />
  );
}

Hãy thử tự mình sửa code trước khi tham khảo lời giải!