+6

Tìm hiểu React Table

Bạn đang tìm kiếm một thư viện trên nền tảng ReactJS giúp bạn hiển thị dữ liệu theo dạng bảng? React Table là một sự lựa chọn khá tuyệt vời.

Cài đặt

Trong bài viết này mình sẽ hướng dẫn các bạn sử dụng React Table, một module của NodeJS. Để sử dụng được React Table, bạn cần cài đặt module cho NodeJS bằng cách chạy lệnh: npm install --save react-table

Cách sử dụng

Đầu tiên, chúng ta phải khai báo ReactTable: import ReactTable from 'react-table' Gọi css ra để bảng hiển thị đẹp hơn import 'react-table/react-table.css' Ví dụ, mình cần hiển thị dữ liệu như sau:

const data = [{
  name: 'Nguyen Van A',
  age: 26,
  friend: {
    name: 'Do Van C',
    age: 23,
  }
}, {
  name: 'Dao Thi B',
  age: 22,
  friend: {
    name: 'Ngo Trung V',
    age: 24,
  }
}, {
  name: 'Tran Duc C',
  age: 25,
  friend: {
    name: 'Ngo Thanh E',
    age: 25,
  }
}, {
  name: 'Le Tien N',
  age: 27,
  friend: {
    name: 'Cao Cong G',
    age: 24,
  }
}, {
  name: 'Pham Hoang M',
  age: 26,
  friend: {
    name: 'Lai Hai D',
    age: 25,
  }
}, {
  name: 'Duong Van L',
  age: 23,
  friend: {
    name: 'Le Hoang M',
    age: 23,
  }
}];

Trước khi gọi component ra ta phải định dạng hiển thị cho các cột của bảng.

const columns = [{
  header: 'Name',
  accessor: 'name' // Cái này sẽ là đại diện cho giá trị của thuộc tính của phần tử ở cột này. Với thuộc tính đơn giản thì chỉ cần truyền vào key của đối tượng trong data.
}, {
  header: 'Age',
  accessor: 'age',
  Cell: props => <span className='number'>{props.value}</span> // Tùy biến component Cell.
}, {
  id: 'friendName', // Khi accessor không phải là 1 chuỗi thì phải cung cấp id để đại diện cho thuộc tính cột.
  header: 'Friend Name',
  accessor: d => d.friend.name // Tùy biến giá trị đại diện cho giá trị của thuộc tính của phần tử ở cột này.
}, {
  header: props => <span>Friend Age</span>, // Tùy biến component Header
  accessor: 'friend.age' // Khi 1 thuộc tính của dữ liệu có kiểu là 1 đối tượng, chúng ta cũng có thể cung cấp đường dẫn đến thuộc tính cần lấy giá trị.
}];

Sau khi có dữ liệu và định dạng hiển thị, ta có thể gọi ra component:

<ReactTable
  data={data}
  columns={columns}
  defaultPageSize={5}
/>

Kết quả sẽ được là:

Một số thành phần

Một số option cho định dạng cột

Một trong những điểm mình thích nhất của thư viện này là ta có thể dễ dàng tuỳ biến lại các thành phần của nó.

Cell: ({value}) => (value >= 18 ? 'Can watch video' : 'Cannot watch video') // Tùy biến lại component Cell, cách hiển thị của dữ liệu ở từng ô trong cột.
sortable: boolean // Cho phép sắp xếp theo cột này hay không?
filterable: boolean // Cho phép lọc theo cột này hay không?
filterMethod: (filter, row, column) => {return true} // Hàm lọc áp dụng khi lọc theo cột này
Filter: ({filter, onChange}) => (
  <select
    value={filter ? filter.value : '0'}
    onChange={event => onChange(event.target.value)}
  >
    <option value='0' />
    <option value='1'>Option 1</option>
    <option value='2'>Option 2</option>
  </select>
) // Tùy biến component Filter, hiển thị ra select box thay vì textbox. Hàm callback onChange truyền vào giá trị là filter.value cho hàm filterMethod.

Một số option lúc gọi component hiển thị bảng

data: [], // Dữ liệu đổ vào bảng
showPagination: boolean, // Hiển thị phân trang hay không
showPageSizeOptions: boolean, // Hiển thị selectbox thay đổi số bản ghi trên 1 trang hay không
pageSizeOptions: [5, 10, 20, 25, 50, 100], //  Các options cho selectbox số bản ghi trên 1 trang
defaultPageSize: integer, // Số bản ghi mặc định trên 1 trang
resizable: boolean, // Cho phép người dùng tự do thay đổi kích thước của các cột hay không
filterable: boolean, // Cho phép lọc dữ liệu hay không
defaultFilterMethod: (filter, row, column) => {return true}, // Hàm lọc mặc định nếu không bị override bởi hàm filterMethod ở từng cột
page: integer, // Hiển thị bảng ở trang số bao nhiêu

Một ví dụ tùy biến component TrGroupComponent

Mình sẽ hiện ra bảng với các dòng có item có age > 25 thì sẽ được bôi màu. Định nghĩa component mới:

const customTrGroupComponent = (props) => {
  var extra_style = null;
  if (props.row.age > 25) {
    extra_style = {
      backgroundColor: '#72AAFF'
    }
  }
  return <div className='rt-tr-group' style={extra_style}>
    {props.children} // Nội dung bên trong bình thường nó sẽ hiển thị
  </div>;
}

Lúc gọi ra component sẽ phải làm thêm 2 việc:

<ReactTable
  data={data}
  columns={columns}
  defaultPageSize={5}
  getTrGroupProps={(state, rowInfo, column, instance) => rowInfo} // Kết quả trả về của hàm này sẽ là props cho component TrGroupComponent mà chúng ta định nghĩa
  TrGroupComponent={customTrGroupComponent} // Khai báo component mới sẽ dùng thay thế cho component mặc định.
/>

Và kết quả sẽ là: Với các component khác của React Table bạn cũng có thể làm tương tự, và phải định nghĩa đúng hàm getProps cho component đó

Cấu trúc đầy đủ components của React Table bình thường

TableComponent
    TheadComponent
        TrComponent
            ThComponent // Nếu cho phép resize cột
                ResizerComponent
            ThComponent // Nếu cho phép lọc dữ liệu
                FilterComponent
    TbodyComponent
        TrGroupComponent
            TrComponent
                PivotComponent // Nếu khai báo gom nhóm dữ liệu theo (các) cột nào đó
                    ExpanderComponent
                    PivotValueComponent
                TdComponent
                    AggregatedComponent // Dữ liệu đại diện cho nhóm các bản ghi khi gộp cột
            TrComponent
                TdComponent // Nếu không khai báo gom nhóm dữ liệu theo cột thì hiển thị bình thường.
    TfootComponent
    PaginationComponent
        PreviousComponent
        NextComponent
    NoDataComponent
    LoadingComponent

Lời kết

Trên đây là bài viết giới thiệu về những điều mà mình đã tìm hiểu được về thư viện React Table. Nếu có vấn đề gì khi sử dụng React Table, hãy comment phía dưới để mình có thể tìm hiểu cùng bạn nhé... Cảm ơn các bạn đã quan tâm đến bài viết. Tham khảo: https://react-table.js.org


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.