Prop và cách truyền prop vào component trong React

0 phút đọc

Trong React, props được sử dụng để truyền thông tin giữa các component. Mọi component cha có thể truyền thông tin đến các component con của nó bằng cách cung cấp chúng props. Props có thể khiến bạn liên tưởng đế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ác đối tượng, mảng và hàm.

Prop và cách truyền prop vào component trong React

Props trong React là gì?

Props là tham số đầu vào của các component trong React. Props là một trong những khái niệm cực kỳ quan trọng của React.

Liên tưởng đơn giản, props trong React chính là các thuộc tính trong HTML. Điểm khác biệt ở đây là chúng ta có thể tự định nghĩa những thuộc tính đó, thay vì với HTML, các thuộc tính được định nghĩa sẵn.

const App = () => {
  const x = 1;
  const y = 2;
  return (
    <div>
      <Sum a={x} b={y} />
    </div>
  )
}

const Sum = (props) => {
  console.log(props) // {a: 1, b: 2}
  return <div>The value is: {props.a + props.b}</div>
}

Props có thể nhận giá trị thuộc tất cả các kiểu dữ liệu trong Javascript. Props chính là phương tiện để lưu chuyển dữ liệu bên trong React.

Props hoàn toàn do chúng ta tự định nghĩa. Các components do chúng ta định nghĩa không hiểu được các giá trị thuộc tính HTML như src, id, className. Chúng đơn thuần là các key trong một object props. Chúng ta sẽ cần gán lại cho các thẻ HTML tương ứng bên trong component.

const App = () => {
  return (
    <div>
      <NameCard className="name-card" id="alice" />
    </div>
  )
}

const NameCard = (props) => {
  return (
    <div className={props.className}>
      <div id={props.id}>Name: Alice</div>
    </div>
  )
}

Props là read-only, nghĩa là chúng ta không thể thay đổi được giá trị props bên trong một component.

Tầm quan trọng của props trong React: props cho phép tạo ra các Component có khả năng tái sử dụng cao. Thay vì dữ liệu được hard-coded bên trong component, props cho phép component có thể nhận được dữ liệu đầu vào mỗi lần sử dụng nó. Đây chính là công cụ để kết nối các component lại với nhau. Vì vậy, props cho phép ứng dụng được chia nhỏ thành nhiều phần.

Cách truyền props vào một component trong React

Trong đoạn code này, component Profile không truyền bất kỳ props nào vào component con của nó, Avatar:

export default function Profile() {
  return <Avatar />;
}

Bạn có thể truyền các props vào Avatar theo hai bước.

Bước 1: Truyền props từ component cha vào component con

Đầu tiên, hãy truyền một số props vào Avatar. Ví dụ, hãy truyền hai props: person (một đối tượng)size (một con số):

export default function Profile() {
  return (
    <Avatar person={{ name: "Lin Lanying", imageId: "1bX5QH6" }} size={100} />
  );
}

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, ví dụ: personsize, được ngăn cách bằng dấu phẩy trong ({ và }) ngay sau hàm Avatar. Điều này cho phép bạn sử dụng chúng bên trong mã của component Avatar, giống như bạn thao tác với 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 personsize để render. Bây giờ bạn có thể cấu hình Avatar để render 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>
  );
}

Giá trị mặc định của props

Nếu bạn muốn đặt một giá trị mặc định cho props để sử dụng khi không có giá trị được chỉ định, bạn có thể làm điều này 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 render mà không có props size, size sẽ được đặt thành 100.

Giá trị mặc định chỉ được sử dụng khi props size bị thiếu hoặc nếu bạn truyền size={undefined}. Tuy nhiên, 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 toàn bộ props

Đôi khi, việc truyền props trở nên 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 mã lặp đi lặp lại - nó có thể dễ đọc hơn. Nhưng đôi khi bạn có thể muốn sự ngắn gọn, bạn có thể sử dụng cách sau:

function Profile(props) {
  return (
    <div className="card">
      <Avatar {...props} />
    </div>
  );
}

Cú pháp này chuyển tiếp tất cả props của Profile cho Avatar mà không cần liệt kê từng tên props.

Children props trong React

Các thẻ HTML có thể chứa bên trong nó các thẻ HTML khác, ví dụ như div, p, ... Tương tự như vậy, các thẻ “HTML” do chúng ta tự tạo cũng có thể làm được điều tương tự thông qua một giá trị props đặc biệt có tên là children. Xét ví dụ sau:

import "./Card.css";

const Card = (props) => {
  return <div className="card">{props.children}</div>
}
.card {
  padding: 10px;
  border: 1px solid black;
  border-radius: 8px;
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}
import Card from "./Card.js";

const App = () => {
  return (
    <Card>
      <div>Inside a card</div>
    </Card>
  )
}

Cũng tương tự như các props thông thường khác, children có thể nhận giá trị là bất cứ kiểu dữ liệu nào. Với ví dụ ở trên, children nhận vào giá trị là một React Element.

children props giúp chúng ta có khả năng “compose” các component lại với nhau. Thay vì cố định giá trị bên trong Card, lúc này Card có thể cho bất cứ component nào nằm trong nó có thêm các thuộc tính CSS ở trên.

Smart & dump components

Xét 2 ví dụ sau:

const Sum = () => {
	const x = 1
	const y = 2
	return <div>{x + y}</div>
}

<Sum />
<Sum />
<Sum />
const Sum = (props) => {
	const {x, y} = props

	return <div>{x + y}</div>
}
 
<Sum x={1} y={2} />
<Sum x={2} y={3} />
<Sum x={7} y={5} />

Trong ví dụ trên thì bên trái, component Sum có xử lý logic bên trong, còn bên phải thì không.

Phần bên trái là một Smart Component, và phần bên phải là một Dump Component. Trong thực tế thì chúng ta viết càng nhiều dump component nghĩa là chúng ta càng smart 🙂

Ở ví dụ bên trái, smart component không thể tái sử dụng, vì mỗi lần chúng ta dùng nó, nó luôn cho kết quả là 3.

Ngược lại, với ví dụ bên phải, dump component có thể được sử dụng để in ra tổng 2 số bất kỳ khi chúng ta truyền giá trị vào bên trong.

Tuy nhiên, không phải lúc nào dump component cũng tốt. Vì nếu cho phép truyền quá nhiều props sẽ dẫn đến code khó đọc và khó bảo trì hơn do nhiều thành phần tham gia vào logic của component hơn. Việc quyết định “dump” / “smart” bao nhiêu là đủ còn tuỳ thuộc khá nhiều vào kinh nghiệm của lập trình viên và từng tình huống xử lý khác nhau

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào

Avatar TechMely Team
Được viết bởi

TechMely Team

Ta không thể bắt đầu lại nhưng ta có thể mở đầu bây giờ và làm nên một kết thúc mới.