React.js list và keys

React.js list và keys

  • key giúp React xác định item nào được thay đổi, được thêm, hoặc được xóa.
  • key dành cho mỗi phần tử trong list, do đó keys của mỗi phần tử phải là duy nhất.
  • Viết tiếp nội dung bài trước như sau:
function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li key={number.toString()}>
      {number * 2}
    </li>
  );
  return (
    <ul>{listItems}</ul>
  );
};

const numbers = [1, 2, 3, 4, 5];

ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

Hiển thị trình duyệt

  • 2
  • 4
  • 6
  • 8
  • 10

Làm thử!

  • Xem lại kết quả console khi này, ta sẽ thấy không còn cảnh báo nữa.
  • Do key mỗi phần tử là duy nhất, nên key thường là giá trị id, trường hợp không có id hoặc giá trị nào đó duy nhất thì ta có thể sử dụng index như là giải pháp cuối cùng.

Sử dụng id làm keys

const todoItems = todos.map((todo) =>
  <li key={todo.id}>
    {todo.text}
  </li>
);

Sử dụng index làm keys

  • Sử dụng trong trường hợp Array không có giá trị duy nhất như id.
  • Tuy nhiên không khuyến khích sử dụng index trong trường hợp thứ tự các mục có khả năng thay đổi, vì có khả năng sẽ làm ảnh hưởng đến State của component.
const todoItems = todos.map((todo, index) =>
  <li key={index}>
    {todo.text}
  </li>
);

Trích xuất component với Keys

  • Chú ý là key chỉ có ý nghĩa trong ngữ cảnh có các mãng đang sử dụng, ví dụ như nếu trích xuất component ListItem, thì ta nên gán key ngay tại <ListItem key={} /> thay vì tại <li> bên trong function ListItem.
Cấu trúc không đúng Cấu trúc đúng
function ListItem(props) {
  const value = props.value;
  return (
    /* Sai: không cần key ở đây */
    <li key={value.toString()}>
      {value}
    </li>
  );
};

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    /* Sai: key nên được sử dụng ở đây: */
    <ListItem value={number * 2} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
};

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);
function ListItem(props) {
  return <li>{props.value}</li>;
};

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    /* Sử dụng đúng */
    <ListItem key={number.toString()}
              value={number * 2} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
};

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

Hiển thị trình duyệt khi sử dụng cấu trúc đúng

  • 2
  • 4
  • 6
  • 8
  • 10

Làm thử!

Keys phải giống nhau trong cùng một component

  • Chú ý là key cần phải đồng nhất khi sử dụng trong cùng một component (hoặc trong cùng một function hay class).
function Tutorial(props) {
  const sidebar = (
    <ul>
      {props.posts.map((post) =>
        <li key={post.id}>
          {post.title}
        </li>
      )}
    </ul>
  );
  const content = props.posts.map((post) =>
    <div key={post.id}>
      <h2>{post.title}</h2>
      <p>{post.content}</p>
    </div>
  );
  return (
    <div>
      {sidebar}
      <hr />
      {content}
    </div>
  );
};

const posts = [
  {id: 1, title: 'Học Javascript', content: 'Chào mừng bạn đền Javascript!'},
  {id: 2, title: 'Học React.js', content: 'Bạn có thể bắt đầu học React.js sau khi cài đặt.'}
];
ReactDOM.render(
  <Tutorial posts={posts} />,
  document.getElementById('root')
);

Hiển thị trình duyệt khi sử dụng cấu trúc đúng

  • Học Javascript
  • Học React.js

Học Javascript

Chào mừng bạn đền Javascript!

Học React.js

Bạn có thể bắt đầu học React.js sau khi cài đặt.

Làm thử!

  • Chú ý là key không phải là một giá trị của component, do đó nếu muốn sử dụng giá trị giống như key thì ta cần phải tạo một props, sử dụng với tên khác.
const content = posts.map((post) =>
  <Post
    key={post.id}
    id={post.id}
    title={post.title} />
);