Reselect là gì và vì sao nó lại được sử dụng rộng rãi trong các ứng dụng React-Redux

1. Selector là gì ?

Selector trong một ứng dụng React-redux có thể hiểu là một đoạn logic được sử dụng để tính toán ra một giá trị nào đó từ các giá trị có sẵn trong Store hoặc chỉ đơn giản là lấy một giá trị có sẵn trong Store.

Chúng ta hoàn toàn có thể tự viết ra Selector cho riêng mình như sau:

// *** selector dùng để lấy property "users" từ store của redux
const getUsers = state => state.users;

// *** selector lấy ra một giá trị từ store thông qua các tham số
const getUserViaId = (state, id) => state.users.map(user => user.id === id);

Nhưng, mối khi users được update, hàm getUserViaId sẽ bị toán lại, và users, và khi users trở nên lớn hơn, hoặc việc tính toán bên trong getUserViaId phức tạp, tốn nhiều tài nguyên thì nó sẽ làm app của chúng ta chậm lại.

2. Reselector

Reselector sẽ giải quyết được vấn đề ở trên nhờ có một số lợi ích dưới đây:

  1. Những tham số được truyền vào trong function createSelector (lát mình sẽ giới thiệu sau, cơ bản thí function này được dùng để tạo ra Selector) sẽ được lưu lại và selector được tạo bởi Reselector sẽ không tính toán lại giá trị mà nó trả về nếu như tham số mới bằng với tham số cũ.
  2. Các selector được tạo ra từ Reselector có thể được lồng với nhau, nghĩa là ta có thể dùng một selector như một tham số cho một selector khác, giúp cho việc quản lý dữ liệu được các selector trả về sẽ cực kỳ dễ dàng.

3. Sử dụng Reselector

File README trong repo của reselector trên github rất chất lượng, dễ đọc và rõ ràng nên mình sẽ chỉ giới thiệu qua cho các bạn cách dùng cơ bản của thư này.

Các bạn có thể vào link này để xem cách hoạt động của Reselector Codepen

Để tạo một Selector từ Reselector, ta sẽ cần dùng đến method createSelector, method này nhận vào các selector hoặc một mảng các selector và cuối cùng là một function, giá trị mà function này trả về cũng chính là giá trị mà selector của reselect trả về. VD:

import { createSelector } from 'reselect'

const getVisibilityFilter = (state) => state.visibilityFilter
const getTodos = (state) => state.todos

// *** selector
import { createSelector } from 'reselect'

const getVisibilityFilter = (state) => state.visibilityFilter
const getTodos = (state) => state.todos

****
export const getVisibleTodos = createSelector(
  [ getVisibilityFilter, getTodos ],
  (visibilityFilter, todos) => {
    switch (visibilityFilter) {
      case 'SHOW_ALL':
        return todos
      case 'SHOW_COMPLETED':
        return todos.filter(t => t.completed)
      case 'SHOW_ACTIVE':
        return todos.filter(t => !t.completed)
    }
  }
)

4. Lời kết

Trên đây là một số điều mà mình muốn giới thiệu với các bạn về Reselect. Mong rằng bài viết này sẽ giúp đỡ được phần nào cho những bạn bước đầu tìm hiểu về Reselect.