Bài 12: ReactJS - List và Keys - Học ReactJS Full Đầy Đủ Nhất

Đăng bởi: Admin | Lượt xem: 3310 | Chuyên mục: Javascript


Trong bài viết này chúng ta sẽ cùng hau đi tìm hiểu về lists và keys trong ReactJS, đây cũng là phần mà chúng ta sẽ làm việc rất nhiều trong React.

1. Lists trong React 

Trong Javascript, bạn muốn tạo một mảng mới từ một mảng có sẵn bằng cách chế biến từng phần tử của mảng ban đầu để tạo ra phần tử tương ứng của mảng mới, bạn có thể sử dụng phương thức map().
Để đơn giản hãy xem ví dụ, bạn có một mảng các số tự nhiên, chẳng hạn [1, 2 , 5], bạn muốn tạo ra một mảng khác bằng cách nhân mỗi phần tử của mảng ban đầu với 10.
var arr1 = [1, 2, 5];
 
console.log(arr1); // --> [1, 2, 5]
 
var arr2 = arr1.map( e  => e * 10 );
 
console.log(arr2); // --> [10, 20, 50]
Trong JSX bạn cũng có thể làm tương tự, từ một mảng các đối tượng (Object), tạo ra một mảng mới chứa các thẻ (Tag):
var array1 = [        
  { empId: 1, fullName: "Trump", gender: "Male" },        
  { empId: 2, fullName: "Ivanka", gender: "Female" },        
  { empId: 3, fullName: "Kushner", gender: "Male" }        
];
 
var array2 = array1.map (
    e =>
    <Emloyee fullName={e.fullName} gender={e.gender} />  
);
Ví dụ 1 :
Trong ví dụ này, tôi có 1 mảng chứa thông tin của các nhân viên (employee), và tôi sẽ hiển thị thông tin của các nhân viên này trên giao diện, giống như hình minh họa dưới đây:
App,jsx
// Employee Component
class Employee extends React.Component {
  render() {
    return (
      <li className="employee">
        <div>
          <b>Full Name:</b> {this.props.fullName}
        </div>
        <div>
          <b>Gender:</b> {this.props.gender}
        </div>
      </li>
    );
  }
}
 
// EmployeeList Component
class EmployeeList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      employees: [
        { empId: 1, fullName: "Trump", gender: "Male" },
        { empId: 2, fullName: "Ivanka", gender: "Female" },
        { empId: 3, fullName: "Kushner", gender: "Male" }
      ]
    };
  }
 
  render() {
    // Array of <Employee>
    var listItems = this.state.employees.map(e => (
      <Employee fullName={e.fullName} gender={e.gender} />
    ));
    return (
        <ul className="employee-list">
           {listItems}
        </ul>
      );
  }
}
 
// Render
ReactDOM.render(<EmployeeList />, document.getElementById("employeelist1"));
lists-example.html
<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <title>ReactJS Lists</title>
      <script src="https://unpkg.com/react@16.4.2/umd/react.production.min.js"></script>
      <script src="https://unpkg.com/react-dom@16.4.2/umd/react-dom.production.min.js"></script>
      <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
 
      <style>
         .employee-list  {
           border:1px solid #cbbfab;
           list-style-type : none;
           padding: 5px;
           margin: 5px;
         }
         .employee {
            border: 1px solid #ccc;
            margin: 5px;
            padding: 5px;
         }
      </style>
   </head>
   <body>
      <h3>React Lists:</h3>
 
      <div id="employeelist1"></div>
 
      <script src="lists-example.jsx" type="text/babel"></script>
   </body>
</html>
Ví dụ 2 :
Ở đây mình sẽ tiến hành khởi tạo một lists các items.
import React from "react";
 
function ListComponent(props) {
  const myList = ["php", "javascript", "python", "C++"];
  const listItems = myList.map((item) =>
    <li>{item}</li>
  );
   
  return (
    <ul>{listItems}</ul>
  );
}
 
export default ListComponent
và trình duyệt sẽ hiện thị kết quả:
  • php
  • javascript
  • python
  • C++
Việc khởi tạo các lists trong React rất đơn giản, điều mình muốn tập trung nhấn mạnh trong bài viết này đó là về keys mà mình sẽ đề cập bên dưới.

2. React Keys

Trong quá trình làm việc với React, chúng ta phải thao tác với danh sách(lists) rất nhiều như danh sách các ảnh, danh sách các item trong giỏ hàng,...Khi các lists này có hàng tá các items thì React rất khó có thể kiểm soát được items. Bởi vậy chúng ta cần phải chỉ định cho nó một key để định danh.
Keys (Khóa) giúp React phân biệt được các item trong một danh sách. Nó giúp React quản lý các item có thay đổi, các item mới được thêm vào, hoặc các item đã bị loại bỏ khỏi danh sách.
Từ một mảng các đối tượng, bạn tạo ra một mảng mới chứa các thẻ (Tag), các thẻ này nên có thuộc tính key, và giá trị của chúng không được phép giống nhau.
keys-example.jsx
// Employee Component
class Employee extends React.Component {
  render() {
    return (
      <li className="employee">
        <div>
          <b>Full Name:</b> {this.props.fullName}
        </div>
        <div>
          <b>Gender:</b> {this.props.gender}
        </div>
      </li>
    );
  }
}
 
// EmployeeList Component
class EmployeeList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      employees: [
        { empId: 1, fullName: "Trump", gender: "Male" },
        { empId: 2, fullName: "Ivanka", gender: "Female" },
        { empId: 3, fullName: "Kushner", gender: "Male" }
      ]
    };
  }
 
  render() {
    // Array of <Employee>
    var listItems = this.state.employees.map(e => (
      <Employee key={e.empId} fullName={e.fullName} gender={e.gender} />
    ));
    return (
        <ul className="employee-list">
           {listItems}
        </ul>
      );
  }
}
 
// Render
ReactDOM.render(<EmployeeList />, document.getElementById("employeelist1"));
key-example.html
<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <title>ReactJS Lists</title>
      <script src="https://unpkg.com/react@16.4.2/umd/react.production.min.js"></script>
      <script src="https://unpkg.com/react-dom@16.4.2/umd/react-dom.production.min.js"></script>
      <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
 
      <style>
         .employee-list  {
           border:1px solid #cbbfab;
           list-style-type : none;
           padding: 5px;
           margin: 5px;
         }
         .employee {
            border: 1px solid #ccc;
            margin: 5px;
            padding: 5px;
         }
      </style>
   </head>
   <body>
      <h3>React Lists:</h3>
 
      <div id="employeelist1"></div>
 
      <script src="keys-example.jsx" type="text/babel"></script>
   </body>
</html>
Nếu bạn chạy ví dụ 2 ở phần thứ 1, React sẽ hiển thị cảnh báo như hình bên dưới:
Để loại bỏ cảnh báo bạn phải chỉ định cho các items trong lists một thuộc tính có tên là key. Chúng ta sẽ sửa ví dụ ở đầu bài thành:
import React from "react";
 
function ListComponent(props) {
  const myList = [
    {
      id : 'p',
      name : 'php'
    },
    {
      id : 'j',
      name : 'javascript'
    },
    {
      id : 'py',
      name : 'python'
    },
    {
      id : 'c',
      name : 'C++'
    },
  ]
 
  //Thêm thuộc tính key vào trong thẻ jsx
  const listItems = myList.map((item) =>
    <li key = {item.id}>{item.name}</li>
  );
 
  return (
    <ul>{listItems}</ul>
  );
}
 
export default ListComponent

3. Một vài lưu ý khi sử dụng Keys

Ở đây mình có một vài lưu ý sử dụng key cho list, các lưu ý này sẽ giúp quá trình làm việc với React không gặp các lỗi không mong muốn.
Keys là duy nhất
Bạn cần chỉ định các keys này là duy nhất, các keys này không được trùng lặp trong các lists.
const myList = [
    {
      id : 'p',
      name : 'php'
    },
    {
      id : 'j',
      name : 'javascript'
    },
    {
      id : 'p',
      name : 'python'
    },
    {
      id : 'c',
      name : 'C++'
    },
  ]
 
  const listItems = myList.map((item) =>
    <li key = {item.id}>{item.name}</li>
  );
khi các keys này trùng lặp bạn sẽ nhận được cảnh báo :
Warning: Encountered two children with the same key, `p`. 
Keys should be unique so that components maintain their identity across updates. 
Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
Các keys chỉ cần là duy nhất khi so sánh với các anh/chị của nó trong lists chứa chúng.
Tránh chỉ định index làm key
Trong một vài trường hợp bạn thường chỉ định giá trị của biến index thành keys như trong ví dú này:
const listItems = myList.map((item, index) =>
  <li key = {index}>{item.name}</li>
);
React khuyên chúng ta không nên sử dụng cách này. Bởi khi bạn thực hiện sắp xếp mảng thì index sẽ thay đổi, React lại phải xác định lại keys môt lần nữa, gây ra giảm hiệu xuất làm việc.
Chỉ sử dụng index làm key trong khi:
  • Nếu list của bạn là tĩnh và sẽ không thay đổi.
  • List sẽ không bao giờ được sắp xếp lại.
  • List sẽ không được lọc (thêm / xóa các mục khỏi danh sách).
  • Không có id cho các mục trong list.
Hãy chỉ sử dụng index làm key trong trường hợp đặc biệt này, và lưu ý trong quá trình sử dụng.

4. Các ví dụ :

Ở ví dụ này mình sẽ tạo một phần tử Content với unique(duy nhất) index(i). Hàm map sẽ tạo ra 3 phần tử từ dữ liệu có sẵn. Vì giá trị key cần phải là duy nhất cho mọi phần tử, mình sẽ gán i làm khoá cho mỗi phần tử được tạo
App.jsx
import React from 'react';

class App extends React.Component {
   constructor() {
      super();
		
      this.state = {
         data:[
            {
               component: 'First...',
               id: 1
            },
            {
               component: 'Second...',
               id: 2
            },
            {
               component: 'Third...',
               id: 3
            }
         ]
      }
   }
   render() {
      return (
         <div>
            <div>
               {this.state.data.map((dynamicComponent, i) => <Content 
                  key = {i} componentData = {dynamicComponent}/>)}
            </div>
         </div>
      );
   }
}
class Content extends React.Component {
   render() {
      return (
         <div>
            <div>{this.props.componentData.component}</div>
            <div>{this.props.componentData.id}</div>
         </div>
      );
   }
}
export default App;
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';

ReactDOM.render(<App/>, document.getElementById('app'));
Các bạn mở terminal là chay dòng lệnh sau :
npm start
Kết quả hiển thị ở hình dưới :
Trên đây chúng ta đã cùng nhau đi tìm hiểu về List và Keys trong ReactJS. Đây là kiến thức rất cơ bản về nó nhưng cũng hết sức quan trọng trong quá trình làm việc với ReactJS sau này. Mong rằng bài viết sẽ giúp ích cho bạn.
Bài tiếp theo: ReactJS - Router >>
vncoder logo

Theo dõi VnCoder trên Facebook, để cập nhật những bài viết, tin tức và khoá học mới nhất!