Truyền props vào 1 Component
Các component React sử dụng props để giao tiếp với nhau. Mỗi component cha có thể truyền một số thông tin cho các component con của nó bằng cách cung cấp cho chúng các props. Props có thể làm bạn nhớ đến các thuộc tính HTML, nhưng bạn có thể truyền bất kỳ giá trị JavaScript nào thông qua chúng, bao gồm cả đối tượng, mảng và hàm.
Bạn sẽ được học
- Cách truyền props cho một component
- Cách đọc props từ một component
- Cách chỉ định các giá trị mặc định cho props
- Cách truyền một số JSX cho một component
- Cách props thay đổi theo thời gian
Các props quen thuộc
Props là thông tin mà bạn truyền cho một thẻ JSX. Ví dụ: className
, src
, alt
, width
và height
là một số props bạn có thể truyền cho một <img>
:
function Avatar() { return ( <img className="avatar" src="https://i.imgur.com/1bX5QH6.jpg" alt="Lin Lanying" width={100} height={100} /> ); } export default function Profile() { return ( <Avatar /> ); }
Các props bạn có thể truyền cho một thẻ <img>
được xác định trước (ReactDOM tuân theo tiêu chuẩn HTML). Nhưng bạn có thể truyền bất kỳ props nào cho các component của riêng bạn, chẳng hạn như <Avatar>
, để tùy chỉnh chúng. Đây là cách thực hiện!
Truyền props cho một component
Trong đoạn code này, component Profile
không truyền bất kỳ props nào cho component con của nó, Avatar
:
export default function Profile() {
return (
<Avatar />
);
}
Bạn có thể cung cấp cho Avatar
một số props trong hai bước.
Bước 1: Truyền props cho component con
Đầu tiên, hãy truyền một số props cho Avatar
. Ví dụ: hãy truyền hai props: person
(một đối tượng) và size
(một số):
export default function Profile() {
return (
<Avatar
person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }}
size={100}
/>
);
}
Bây giờ bạn có thể đọc các props này bên trong component Avatar
.
Bước 2: Đọc props bên trong component con
Bạn có thể đọc các props này bằng cách liệt kê tên của chúng person, size
được phân tách bằng dấu phẩy bên trong ({
và })
ngay sau function Avatar
. Điều này cho phép bạn sử dụng chúng bên trong code Avatar
, giống như bạn làm với một biến.
function Avatar({ person, size }) {
// person và size có sẵn ở đây
}
Thêm một số logic vào Avatar
sử dụng các props person
và size
để hiển thị, và bạn đã hoàn thành.
Bây giờ bạn có thể định cấu hình Avatar
để hiển thị theo nhiều cách khác nhau với các props khác nhau. Hãy thử điều chỉnh các giá trị!
import { getImageUrl } from './utils.js'; function Avatar({ person, size }) { return ( <img className="avatar" src={getImageUrl(person)} alt={person.name} width={size} height={size} /> ); } export default function Profile() { return ( <div> <Avatar size={100} person={{ name: 'Katsuko Saruhashi', imageId: 'YfeOqp2' }} /> <Avatar size={80} person={{ name: 'Aklilu Lemma', imageId: 'OKS67lh' }} /> <Avatar size={50} person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }} /> </div> ); }
Props cho phép bạn suy nghĩ về các component cha và con một cách độc lập. Ví dụ: bạn có thể thay đổi các props person
hoặc size
bên trong Profile
mà không cần phải suy nghĩ về cách Avatar
sử dụng chúng. Tương tự, bạn có thể thay đổi cách Avatar
sử dụng các props này mà không cần nhìn vào Profile
.
Bạn có thể coi props như “các núm” mà bạn có thể điều chỉnh. Chúng đóng vai trò tương tự như các đối số cho các hàm—thực tế, props là đối số duy nhất cho component của bạn! Các hàm component React chấp nhận một đối số duy nhất, một đối tượng props
:
function Avatar(props) {
let person = props.person;
let size = props.size;
// ...
}
Thông thường, bạn không cần toàn bộ đối tượng props
mà chỉ cần tách nó thành các props riêng lẻ.
Chỉ định một giá trị mặc định cho một prop
Nếu bạn muốn cung cấp cho một prop một giá trị mặc định để dự phòng khi không có giá trị nào được chỉ định, bạn có thể thực hiện việc đó bằng cách destructuring bằng cách đặt =
và giá trị mặc định ngay sau tham số:
function Avatar({ person, size = 100 }) {
// ...
}
Bây giờ, nếu <Avatar person={...} />
được hiển thị mà không có prop size
, thì size
sẽ được đặt thành 100
.
Giá trị mặc định chỉ được sử dụng nếu prop size
bị thiếu hoặc nếu bạn truyền size={undefined}
. Nhưng nếu bạn truyền size={null}
hoặc size={0}
, giá trị mặc định sẽ không được sử dụng.
Chuyển tiếp props với cú pháp spread JSX
Đôi khi, việc truyền props trở nên rất lặp đi lặp lại:
function Profile({ person, size, isSepia, thickBorder }) {
return (
<div className="card">
<Avatar
person={person}
size={size}
isSepia={isSepia}
thickBorder={thickBorder}
/>
</div>
);
}
Không có gì sai với code lặp đi lặp lại—nó có thể dễ đọc hơn. Nhưng đôi khi bạn có thể coi trọng sự ngắn gọn. Một số component chuyển tiếp tất cả các props của chúng cho các component con của chúng, giống như cách Profile
này làm với Avatar
. Vì chúng không sử dụng bất kỳ props nào của chúng trực tiếp, nên có thể hợp lý khi sử dụng cú pháp “spread” ngắn gọn hơn:
function Profile(props) {
return (
<div className="card">
<Avatar {...props} />
</div>
);
}
Điều này chuyển tiếp tất cả các props của Profile
cho Avatar
mà không cần liệt kê từng tên của chúng.
Sử dụng cú pháp spread một cách hạn chế. Nếu bạn đang sử dụng nó trong mọi component khác, thì có điều gì đó không ổn. Thông thường, nó chỉ ra rằng bạn nên chia các component của mình và truyền các children dưới dạng JSX. Thêm về điều đó tiếp theo!
Truyền JSX dưới dạng children
Việc lồng các thẻ trình duyệt tích hợp sẵn là điều phổ biến:
<div>
<img />
</div>
Đôi khi bạn sẽ muốn lồng các component của riêng bạn theo cùng một cách:
<Card>
<Avatar />
</Card>
Khi bạn lồng nội dung bên trong một thẻ JSX, component cha sẽ nhận nội dung đó trong một prop có tên là children
. Ví dụ: component Card
bên dưới sẽ nhận một prop children
được đặt thành <Avatar />
và hiển thị nó trong một div bao bọc:
import Avatar from './Avatar.js'; function Card({ children }) { return ( <div className="card"> {children} </div> ); } export default function Profile() { return ( <Card> <Avatar size={100} person={{ name: 'Katsuko Saruhashi', imageId: 'YfeOqp2' }} /> </Card> ); }
Hãy thử thay thế <Avatar>
bên trong <Card>
bằng một số văn bản để xem component Card
có thể bao bọc bất kỳ nội dung lồng nhau nào. Nó không cần phải “biết” những gì đang được hiển thị bên trong nó. Bạn sẽ thấy mẫu linh hoạt này ở nhiều nơi.
Bạn có thể coi một component có prop children
như có một “lỗ” có thể được “lấp đầy” bởi các component cha của nó bằng JSX tùy ý. Bạn sẽ thường sử dụng prop children
cho các trình bao bọc trực quan: bảng điều khiển, lưới, v.v.

Illustrated by Rachel Lee Nabors
Cách props thay đổi theo thời gian
Component Clock
bên dưới nhận hai props từ component cha của nó: color
và time
. (Code của component cha bị bỏ qua vì nó sử dụng state, mà chúng ta sẽ không đi sâu vào ngay bây giờ.)
Hãy thử thay đổi màu trong hộp chọn bên dưới:
export default function Clock({ color, time }) { return ( <h1 style={{ color: color }}> {time} </h1> ); }
Ví dụ này minh họa rằng một component có thể nhận các props khác nhau theo thời gian. Props không phải lúc nào cũng tĩnh! Ở đây, prop time
thay đổi mỗi giây và prop color
thay đổi khi bạn chọn một màu khác. Props phản ánh dữ liệu của một component tại bất kỳ thời điểm nào, thay vì chỉ trong lúc ban đầu.
Tuy nhiên, props là bất biến—một thuật ngữ từ khoa học máy tính có nghĩa là “không thể thay đổi”. Khi một component cần thay đổi các props của nó (ví dụ: để đáp ứng tương tác của người dùng hoặc dữ liệu mới), nó sẽ phải “yêu cầu” component cha của nó truyền cho nó các props khác nhau—một đối tượng mới! Các props cũ của nó sau đó sẽ bị loại bỏ và cuối cùng công cụ JavaScript sẽ thu hồi bộ nhớ mà chúng chiếm giữ.
Đừng cố gắng “thay đổi props”. Khi bạn cần phản hồi đầu vào của người dùng (như thay đổi màu đã chọn), bạn sẽ cần “đặt state”, bạn có thể tìm hiểu về điều đó trong State: Bộ nhớ của Component.
Tóm tắt
- Để truyền props, hãy thêm chúng vào JSX, giống như bạn làm với các thuộc tính HTML.
- Để đọc props, hãy sử dụng cú pháp destructuring
function Avatar({ person, size })
. - Bạn có thể chỉ định một giá trị mặc định như
size = 100
, được sử dụng cho các props bị thiếu vàundefined
. - Bạn có thể chuyển tiếp tất cả các props bằng cú pháp spread JSX
<Avatar {...props} />
, nhưng đừng lạm dụng nó! - JSX lồng nhau như
<Card><Avatar /></Card>
sẽ xuất hiện dưới dạng propchildren
của componentCard
. - Props là các ảnh chụp chỉ đọc tại một thời điểm: mỗi lần hiển thị nhận được một phiên bản props mới.
- Bạn không thể thay đổi props. Khi bạn cần tương tác, bạn sẽ cần đặt state.
Challenge 1 of 3: Trích xuất một component
Component Gallery
này chứa một số đánh dấu rất giống nhau cho hai profile. Hãy trích xuất một component Profile
ra khỏi nó để giảm sự trùng lặp. Bạn sẽ cần chọn những props nào để truyền cho nó.
import { getImageUrl } from './utils.js'; export default function Gallery() { return ( <div> <h1>Notable Scientists</h1> <section className="profile"> <h2>Maria Skłodowska-Curie</h2> <img className="avatar" src={getImageUrl('szV5sdG')} alt="Maria Skłodowska-Curie" width={70} height={70} /> <ul> <li> <b>Profession: </b> physicist and chemist </li> <li> <b>Awards: 4 </b> (Nobel Prize in Physics, Nobel Prize in Chemistry, Davy Medal, Matteucci Medal) </li> <li> <b>Discovered: </b> polonium (chemical element) </li> </ul> </section> <section className="profile"> <h2>Katsuko Saruhashi</h2> <img className="avatar" src={getImageUrl('YfeOqp2')} alt="Katsuko Saruhashi" width={70} height={70} /> <ul> <li> <b>Profession: </b> geochemist </li> <li> <b>Awards: 2 </b> (Miyake Prize for geochemistry, Tanaka Prize) </li> <li> <b>Discovered: </b> a method for measuring carbon dioxide in seawater </li> </ul> </section> </div> ); }