Bắt đầu nhanh
Chào mừng bạn đến với tài liệu React! Trang này sẽ cung cấp cho bạn phần giới thiệu về 80% các khái niệm React mà bạn sẽ sử dụng hàng ngày.
Bạn sẽ được học
- Cách tạo và lồng các component
- Cách thêm markup và style
- Cách hiển thị dữ liệu
- Cách render điều kiện và danh sách
- Cách phản hồi sự kiện và cập nhật giao diện
- Cách chia sẻ dữ liệu giữa các component
Tạo và lồng các component
Ứng dụng React được xây dựng từ component. Một component là một phần của giao diện người dùng (UI) có logic và giao diện riêng. Một component có thể nhỏ như một nút bấm, hoặc lớn như cả một trang.
Các component trong React là các hàm JavaScript trả về markup:
function MyButton() {
return (
<button>Tôi là một nút bấm</button>
);
}
Các từ khóa export default
chỉ định component chính trong tệp. Nếu bạn không quen với cú pháp JavaScript nào đó, MDN và javascript.info có các tài liệu tham khảo tuyệt vời.
Viết markup với JSX
Cú pháp markup bạn thấy ở trên được gọi là JSX. Nó là tùy chọn, nhưng hầu hết các dự án React sử dụng JSX vì sự tiện lợi của nó. Tất cả các công cụ chúng tôi khuyên dùng để phát triển cục bộ đều hỗ trợ JSX ngay lập tức.
JSX chặt chẽ hơn HTML. Bạn phải đóng các thẻ như <br />
. Component của bạn cũng không thể trả về nhiều thẻ JSX. Bạn phải bọc chúng trong một phần tử cha chung, như <div>...</div>
hoặc một trình bao bọc <>...</>
trống:
function AboutPage() {
return (
<>
<h1>Giới thiệu</h1>
<p>Xin chào.<br />Bạn khỏe không?</p>
</>
);
}
Nếu bạn có nhiều HTML cần chuyển sang JSX, bạn có thể sử dụng công cụ chuyển đổi trực tuyến.
Thêm kiểu dáng
Trong React, bạn chỉ định một lớp CSS với className
. Nó hoạt động theo cùng một cách như thuộc tính class
HTML:
<img className="avatar" />
Sau đó, bạn viết các quy tắc CSS cho nó trong một tệp CSS riêng:
/* Trong CSS của bạn */
.avatar {
border-radius: 50%;
}
React không quy định cách bạn thêm tệp CSS. Trong trường hợp đơn giản nhất, bạn sẽ thêm thẻ <link>
vào HTML của bạn. Nếu bạn sử dụng một công cụ xây dựng hoặc một framework, hãy tham khảo tài liệu của nó để tìm hiểu cách thêm một tệp CSS vào dự án của bạn.
Hiển thị dữ liệu
JSX cho phép bạn đưa markup vào JavaScript. Dấu ngoặc nhọn cho phép bạn “thoát trở lại” JavaScript để bạn có thể nhúng một số biến từ mã của bạn và hiển thị nó cho người dùng. Ví dụ: điều này sẽ hiển thị user.name
:
return (
<h1>
{user.name}
</h1>
);
Bạn cũng có thể “thoát vào JavaScript” từ các thuộc tính JSX, nhưng bạn phải sử dụng dấu ngoặc nhọn thay vì dấu ngoặc kép. Ví dụ: className="avatar"
chuyển chuỗi "avatar"
làm lớp CSS, nhưng src={user.imageUrl}
đọc giá trị biến JavaScript user.imageUrl
và sau đó chuyển giá trị đó làm thuộc tính src
:
return (
<img
className="avatar"
src={user.imageUrl}
/>
);
Bạn cũng có thể đặt các biểu thức phức tạp hơn bên trong dấu ngoặc nhọn JSX, ví dụ: nối chuỗi:
const user = { name: 'Hedy Lamarr', imageUrl: 'https://i.imgur.com/yXOvdOSs.jpg', imageSize: 90, }; export default function Profile() { return ( <> <h1>{user.name}</h1> <img className="avatar" src={user.imageUrl} alt={'Photo of ' + user.name} style={{ width: user.imageSize, height: user.imageSize }} /> </> ); }
Trong ví dụ trên, style={{}}
không phải là một cú pháp đặc biệt, mà là một đối tượng {}
thông thường bên trong dấu ngoặc nhọn JSX style={ }
. Bạn có thể sử dụng thuộc tính style
khi kiểu dáng của bạn phụ thuộc vào các biến JavaScript.
Render có điều kiện
Trong React, không có cú pháp đặc biệt để viết các điều kiện. Thay vào đó, bạn sẽ sử dụng các kỹ thuật tương tự như khi viết mã JavaScript thông thường. Ví dụ: bạn có thể sử dụng câu lệnh if
để bao gồm JSX có điều kiện:
let content;
if (isLoggedIn) {
content = <AdminPanel />;
} else {
content = <LoginForm />;
}
return (
<div>
{content}
</div>
);
Nếu bạn thích mã ngắn gọn hơn, bạn có thể sử dụng toán tử ?
có điều kiện. Không giống như if
, nó hoạt động bên trong JSX:
<div>
{isLoggedIn ? (
<AdminPanel />
) : (
<LoginForm />
)}
</div>
Khi bạn không cần nhánh else
, bạn cũng có thể sử dụng cú pháp logic &&
ngắn hơn:
<div>
{isLoggedIn && <AdminPanel />}
</div>
Tất cả các phương pháp này cũng hoạt động để chỉ định các thuộc tính có điều kiện. Nếu bạn không quen thuộc với một số cú pháp JavaScript này, bạn có thể bắt đầu bằng cách luôn sử dụng if...else
.
Render danh sách
Bạn sẽ dựa vào các tính năng JavaScript như for
loop và array map()
function để render danh sách các component.
Ví dụ: giả sử bạn có một mảng các sản phẩm:
const products = [
{ title: 'Cabbage', id: 1 },
{ title: 'Garlic', id: 2 },
{ title: 'Apple', id: 3 },
];
Bên trong component của bạn, hãy sử dụng hàm map()
để chuyển đổi một mảng các sản phẩm thành một mảng các mục <li>
:
const listItems = products.map(product =>
<li key={product.id}>
{product.title}
</li>
);
return (
<ul>{listItems}</ul>
);
Lưu ý cách <li>
có thuộc tính key
. Đối với mỗi mục trong danh sách, bạn nên chuyển một chuỗi hoặc một số xác định duy nhất mục đó giữa các mục cùng cấp của nó. Thông thường, một key sẽ đến từ dữ liệu của bạn, chẳng hạn như ID cơ sở dữ liệu. React sử dụng các key của bạn để biết điều gì đã xảy ra nếu sau này bạn chèn, xóa hoặc sắp xếp lại các mục.
const products = [ { title: 'Cabbage', isFruit: false, id: 1 }, { title: 'Garlic', isFruit: false, id: 2 }, { title: 'Apple', isFruit: true, id: 3 }, ]; export default function ShoppingList() { const listItems = products.map(product => <li key={product.id} style={{ color: product.isFruit ? 'magenta' : 'darkgreen' }} > {product.title} </li> ); return ( <ul>{listItems}</ul> ); }
Phản hồi các sự kiện
Bạn có thể phản hồi các sự kiện bằng cách khai báo các hàm xử lý sự kiện bên trong các component của bạn:
function MyButton() {
function handleClick() {
alert('You clicked me!');
}
return (
<button onClick={handleClick}>
Click me
</button>
);
}
Lưu ý cách onClick={handleClick}
không có dấu ngoặc đơn ở cuối! Không gọi hàm xử lý sự kiện: bạn chỉ cần truyền nó xuống. React sẽ gọi trình xử lý sự kiện của bạn khi người dùng nhấp vào nút.
Cập nhật màn hình
Thông thường, bạn sẽ muốn component của mình “ghi nhớ” một số thông tin và hiển thị nó. Ví dụ: có thể bạn muốn đếm số lần một nút được nhấp. Để thực hiện việc này, hãy thêm state vào component của bạn.
Đầu tiên, hãy nhập useState
từ React:
import { useState } from 'react';
Bây giờ bạn có thể khai báo một biến trạng thái bên trong component của bạn:
function MyButton() {
const [count, setCount] = useState(0);
// ...
Bạn sẽ nhận được hai thứ từ useState
: trạng thái hiện tại (count
) và hàm cho phép bạn cập nhật nó (setCount
). Bạn có thể đặt cho chúng bất kỳ tên nào, nhưng quy ước là viết [something, setSomething]
.
Lần đầu tiên nút được hiển thị, count
sẽ là 0
vì bạn đã chuyển 0
cho useState()
. Khi bạn muốn thay đổi trạng thái, hãy gọi setCount()
và chuyển giá trị mới cho nó. Nhấp vào nút này sẽ tăng bộ đếm:
function MyButton() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<button onClick={handleClick}>
Clicked {count} times
</button>
);
}
React sẽ gọi lại hàm component của bạn. Lần này, count
sẽ là 1
. Sau đó nó sẽ là 2
. Vân vân.
Nếu bạn render cùng một component nhiều lần, mỗi component sẽ có state riêng. Nhấp vào từng nút riêng biệt:
import { useState } from 'react'; export default function MyApp() { return ( <div> <h1>Counters that update separately</h1> <MyButton /> <MyButton /> </div> ); } function MyButton() { const [count, setCount] = useState(0); function handleClick() { setCount(count + 1); } return ( <button onClick={handleClick}> Clicked {count} times </button> ); }
Lưu ý cách mỗi nút “ghi nhớ” trạng thái count
riêng của nó và không ảnh hưởng đến các nút khác.
Sử dụng Hooks
Các hàm bắt đầu bằng use
được gọi là Hooks. useState
là một Hook tích hợp được cung cấp bởi React. Bạn có thể tìm thấy các Hook tích hợp khác trong API reference. Bạn cũng có thể viết Hooks của riêng mình bằng cách kết hợp các Hook hiện có.
Hooks có tính hạn chế hơn các hàm khác. Bạn chỉ có thể gọi Hooks ở đầu các component của bạn (hoặc các Hook khác). Nếu bạn muốn sử dụng useState
trong một điều kiện hoặc một vòng lặp, hãy trích xuất một component mới và đặt nó ở đó.
Chia sẻ dữ liệu giữa các component
Trong ví dụ trước, mỗi MyButton
có count
độc lập của riêng nó và khi mỗi nút được nhấp, chỉ có count
cho nút được nhấp thay đổi:


Ban đầu, trạng thái count
của mỗi MyButton
là 0


MyButton
đầu tiên cập nhật count
của nó thành 1
Tuy nhiên, thông thường bạn sẽ cần các component chia sẻ dữ liệu và luôn cập nhật cùng nhau.
Để làm cho cả hai component MyButton
hiển thị cùng một count
và cập nhật cùng nhau, bạn cần di chuyển trạng thái từ các nút riêng lẻ “lên trên” đến component gần nhất chứa tất cả chúng.
Trong ví dụ này, đó là MyApp
:


Ban đầu, trạng thái count
của MyApp
là 0
và được truyền xuống cho cả hai con


Khi nhấp vào, MyApp
cập nhật trạng thái count
của nó thành 1
và truyền nó xuống cho cả hai con
Bây giờ, khi bạn nhấp vào một trong hai nút, count
trong MyApp
sẽ thay đổi, điều này sẽ thay đổi cả hai count
trong MyButton
. Đây là cách bạn có thể thể hiện điều này trong mã.
Đầu tiên, di chuyển trạng thái lên từ MyButton
vào MyApp
:
export default function MyApp() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<div>
<h1>Counters that update separately</h1>
<MyButton />
<MyButton />
</div>
);
}
function MyButton() {
// ... we're moving code from here ...
}
Sau đó, truyền trạng thái xuống từ MyApp
cho mỗi MyButton
, cùng với trình xử lý nhấp được chia sẻ. Bạn có thể truyền thông tin đến MyButton
bằng cách sử dụng dấu ngoặc nhọn JSX, giống như bạn đã làm trước đây với các thẻ tích hợp như <img>
:
export default function MyApp() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<div>
<h1>Counters that update together</h1>
<MyButton count={count} onClick={handleClick} />
<MyButton count={count} onClick={handleClick} />
</div>
);
}
Thông tin bạn truyền xuống như thế này được gọi là props. Bây giờ component MyApp
chứa trạng thái count
và trình xử lý sự kiện handleClick
và truyền cả hai xuống dưới dạng props cho mỗi nút.
Cuối cùng, hãy thay đổi MyButton
để đọc các props mà bạn đã truyền từ component mẹ của nó:
function MyButton({ count, onClick }) {
return (
<button onClick={onClick}>
Clicked {count} times
</button>
);
}
Khi bạn nhấp vào nút, trình xử lý onClick
sẽ kích hoạt. Prop onClick
của mỗi nút được đặt thành hàm handleClick
bên trong MyApp
, vì vậy mã bên trong nó sẽ chạy. Mã đó gọi setCount(count + 1)
, tăng biến trạng thái count
. Giá trị count
mới được truyền dưới dạng một prop cho mỗi nút, vì vậy tất cả chúng đều hiển thị giá trị mới. Điều này được gọi là “lifting state up”. Bằng cách di chuyển trạng thái lên, bạn đã chia sẻ nó giữa các component.
import { useState } from 'react'; export default function MyApp() { const [count, setCount] = useState(0); function handleClick() { setCount(count + 1); } return ( <div> <h1>Counters that update together</h1> <MyButton count={count} onClick={handleClick} /> <MyButton count={count} onClick={handleClick} /> </div> ); } function MyButton({ count, onClick }) { return ( <button onClick={onClick}> Clicked {count} times </button> ); }
Các bước tiếp theo
Đến bây giờ, bạn đã biết những điều cơ bản về cách viết mã React!
Hãy xem Tutorial để đưa chúng vào thực tế và xây dựng ứng dụng mini đầu tiên của bạn với React.