Menu

Props trong React: truyền dữ liệu cho component kèm ví dụ

Props là đầu vào của một component React: những giá trị component cha truyền cho component con dưới dạng thuộc tính JSX. Tìm hiểu cách truyền và destructure props, đặt giá trị mặc định, truyền hàm, spread props và vì sao props chỉ đọc.

Trang này có trình soạn thảo chạy trực tiếp. Sửa, chạy và xem đầu ra ngay lập tức.

Props là đầu vào của một component React. Component cha truyền chúng dưới dạng thuộc tính trong JSX, <UserCard name="Ada" online={true} />, và component con nhận chúng trong một đối tượng duy nhất, thường được destructure ngay trong tham số của hàm. Props cho phép một component hiển thị dữ liệu khác nhau mỗi lần bạn dùng nó.

Cùng một UserCard render ra ba người khác nhau. Để ý thẻ cuối cùng: một thuộc tính không có giá trị, online, nghĩa là online={true}. Hãy thêm thẻ thứ tư với tên và vai trò của bạn.

Truyền và đọc props

Truyền chuỗi trong dấu ngoặc kép, còn mọi giá trị khác trong ngoặc nhọn: số, boolean, mảng, đối tượng, hàm, thậm chí cả JSX.

<Product
    title="Desk lamp"
    price={39.5}
    inStock={false}
    tags={['light', 'office']}
    seller={{ name: 'Lumen', rating: 4.8 }}
/>

React gom tất cả thuộc tính vào một đối tượng và truyền nó làm đối số đầu tiên của component. Bạn có thể đọc nó qua props, hoặc tách ngay các trường cần dùng trong danh sách tham số:

function Product(props) {
    return <h3>{props.title}</h3>;
}

function Product({ title, price, seller }) {
    return <h3>{title}, ${price} from {seller.name}</h3>;
}

Cả hai cách đều nhận cùng một đối tượng. Destructuring là cách viết phổ biến vì khi đó chữ ký hàm liệt kê chính xác những props mà component dùng.

Giá trị mặc định

Đặt giá trị mặc định cho prop bằng cú pháp mặc định khi destructuring của JavaScript, = value. Giá trị này được dùng khi component cha bỏ qua prop, hoặc truyền undefined. Nó không áp dụng cho null, 0, false hay '', vì đó là những giá trị thật.

Ba nút đầu tiên dùng giá trị mặc định ở những chỗ prop bị thiếu hoặc là undefined. Nút cuối cùng truyền null, nên size thật sự là null, và phép tra cứu không tìm thấy padding nào. Đổi size={null} thành size="small" để sửa.

Code cũ đặt giá trị mặc định bằng một thuộc tính tĩnh, Button.defaultProps = { size: 'medium' }. React 19 đã bỏ defaultProps cho function component: JSX bỏ qua nó trên một hàm mà không hề cảnh báo. Nó vẫn chạy trên class component. Hãy dùng giá trị mặc định khi destructuring.

Truyền hàm qua props

Dữ liệu chảy xuống: component cha truyền props cho các component con, không bao giờ theo chiều ngược lại. Khi component con cần báo cho cha biết có chuyện gì xảy ra, component cha truyền một hàm và component con gọi hàm đó. Theo quy ước, những prop này được đặt tên dạng onSomething.

Rating không lưu gì cả. Nó hiển thị value nhận được và báo các cú nhấn qua onRate. State nằm ở App, nơi truyền nó xuống lại. Truyền thẳng onRate={setRating} thay cho handleRate vẫn chạy: hàm set cũng là một hàm. Chuyển state vào component cha chung như thế này gọi là lifting state up.

Spread props

Khi bạn đã có một đối tượng có các khóa khớp với props của component, hãy spread nó bằng {...object} thay vì viết từng thuộc tính. Cú pháp rest làm điều ngược lại trong danh sách tham số: lấy vài props theo tên, gom mọi thứ còn lại và chuyển tiếp chúng.

Avatar thứ hai spread person rồi đặt color: khi cùng một prop xuất hiện hai lần, giá trị sau thắng, nên hãy đặt phần ghi đè sau phần spread. TextField giữ label cho riêng mình và chuyển thẳng type, placeholder và maxLength xuống <input>. Hãy dùng spread cho những wrapper như thế này; ở chỗ khác, liệt kê props rõ ràng giúp dễ thấy component nhận được gì hơn.

Props chỉ đọc

Một component không bao giờ được thay đổi props của chính nó. Props thuộc về component cha, và cùng một đối tượng có thể được dùng chung. Hãy coi chúng như các đối số hàm mà bạn không được phép gán lại:

function Counter({ count }) {
    count = count + 1; // wrong: changes a local copy, the parent never sees it
    return <p>{count}</p>;
}

function Profile(props) {
    props.name = 'Someone else'; // wrong: in development React freezes props, so this throws a TypeError
    return <p>{props.name}</p>;
}

Dù vậy, props vẫn thay đổi theo thời gian. Khi component cha render lại với giá trị mới, component con nhận một đối tượng props mới và render theo nó:

Temperature không bao giờ thay đổi celsius. Nó tính fahrenheit từ đó ở mỗi lần render. Kéo thanh trượt, state của component cha thay đổi, nên component con nhận được prop mới. Nếu component con cần một giá trị mà nó có thể tự thay đổi, giá trị đó là state, không phải prop.

Props và state

Props và state đều là những giá trị JavaScript thông thường ảnh hưởng đến những gì component render, và thay đổi một trong hai đều khiến component render lại. Điểm khác nhau là ai sở hữu giá trị đó.

PropsState
Đến từComponent cha, dưới dạng thuộc tính JSXChính component, từ useState hoặc useReducer
Component có thay đổi được khôngKhông, nó chỉ đọcCó, qua hàm set của nó
Cách dùng thường gặpCấu hình component: một nhãn, một kích thước, dữ liệu cần hiển thịGhi nhớ thứ thay đổi: chữ trong ô nhập, một menu đang mở

Cùng một giá trị thường là cả hai. Trong ví dụ nhiệt độ ở trên, celsius là state trong App và là prop trong Temperature. Component sở hữu giữ nó dưới dạng state và truyền xuống dưới dạng prop, kèm theo một hàm để thay đổi nó khi component con cần.

Một prop có thể chứa bất kỳ giá trị nào, kể cả JSX và component. Truyền một element như icon={<StarIcon />} cho phép component cha lấp đầy một chỗ trống trong component con, cùng ý tưởng với children nhưng với tên do bạn chọn.

Prop children

Bất cứ thứ gì bạn đặt giữa thẻ mở và thẻ đóng của một component đều được truyền vào dưới dạng prop tên children. Đây là cách bạn xây dựng các wrapper như card, panel và layout mà không cần biết trước nội dung của chúng:

Trang children trình bày cách truyền nhiều slot và làm việc với children một cách an toàn.

Key không phải là prop

key trông giống một thuộc tính, nhưng React giữ nó cho riêng mình để ghép cặp các phần tử danh sách giữa các lần render. Component không bao giờ nhận được nó:

Console hiển thị props.key là undefined và props.id với giá trị thật. Khi component con cần mã định danh, hãy truyền nó thêm lần nữa dưới tên khác, như id ở đây. Bản build development cũng cảnh báo khi bạn đọc props.key; bản xem trước chạy giống bản build production, nên bạn chỉ thấy undefined.

Câu hỏi thường gặp

Props trong React là gì?

Props (viết tắt của properties) là các đối số của một component. Component cha truyền chúng dưới dạng thuộc tính JSX, <Avatar size={48} />, và component con nhận chúng trong một đối tượng duy nhất, thường được destructure: function Avatar({ size }).

Đặt giá trị mặc định cho một prop như thế nào?

Dùng giá trị mặc định khi destructuring: function Button({ size = 'medium' }). Giá trị mặc định được dùng khi prop bị thiếu hoặc là undefined. React 19 đã bỏ defaultProps cho function component; class component vẫn hỗ trợ.

Component con có thay đổi được props của nó không?

Không. Props chỉ đọc. Để thay đổi những gì component con hiển thị, component cha truyền props mới; để component con yêu cầu thay đổi, component cha truyền một hàm như onChange và component con gọi hàm đó.

Props và state khác nhau thế nào?

Props đến từ component cha và component con không thể thay đổi chúng. State thuộc về chính component và thay đổi qua hàm set của nó. Một giá trị thường là state ở component cha và là prop ở các component con.

Vì sao props.key là undefined?

key (giống ref trong các phiên bản React cũ) được chính React dùng để theo dõi các phần tử trong danh sách và không được truyền vào component. Nếu component con cần giá trị đó, hãy truyền lại dưới tên khác, ví dụ <Row key={id} id={id} />.

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu