12/08/2018, 17:47

Tìm hiểu về Reselect và ý nghĩa của nó

Reselect là một thư viện được sử dụng để tạo ra các memoized selector. Đây chỉ là một cách nói hài hước về việc nó lưu trữ các kết quả của một hàm gồm biến truyền vào. Nó thường được sử dúng với Redux, và thuật ngữ "selector" thường được sử dụng trong hệ sinh thái Redux, đề cập đến cách chọn một ...

Reselect là một thư viện được sử dụng để tạo ra các memoized selector. Đây chỉ là một cách nói hài hước về việc nó lưu trữ các kết quả của một hàm gồm biến truyền vào. Nó thường được sử dúng với Redux, và thuật ngữ "selector" thường được sử dụng trong hệ sinh thái Redux, đề cập đến cách chọn một phần của Redux state Một "selector" có thể tính toán bất kỳ bộ dữ liệu có nguồn gốc nào dựa trên bất kỳ đầu vào tuỳ ý nào, lưu trữ kết quả của hàm để có thể sử dụng vào lần sau. Nó sẽ tính toán lại bất cứ khi nào biến truyền vào được thay đổi. Điều này rất tiện lợi vì 2 lý do:

  1. Các Expensive operation chỉ được thực thi khi cần, giúp tăng hiệu suất tính toán
  2. Các kết quả được lưu vào bộ nhớ cache nên những lần gọi tiếp sau của hàm sẽ được lưu trữ. Sau đó, khi kết quả của memoized selector được sử dụng như một props của component khác, React sẽ biết rằng nó không cần phải re-render lại các sub-component

Tìm hiểu README trên Reselect Page, có vẻ khá rõ ràng rằng thư viện này chỉ được sử dụng cho Redux. Tuy nhiên, sẽ không có gì đặc biệt nếu như nó chỉ được sử dụng trong môi trường Redux. Chắc chắn, nó được tạo ra để giải quyết các vấn đề trong hệ sinh thái Redux, nhưng thực sự, thư viện này rất hữu ích khi bất kỳ time props bị biến đổi trong chuỗi component của bạn và cần phải được ghi nhớ để hiển thị. Các ví dụ từ README nói về mapStateToProps , nó là một mẫu chung với thư viện React-Redux. Theo kinh nghiệm của tôi, thư viện này là một phao cứu sinh cho nhiều ứng dụng không sử dụng Redux

Tạo một Memoized Selector

Bây giờ ta sẽ tạo một Selector. Ta tạo theo code ở dưới đây:

selectors/index.js

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)
    }
  }
)

Trong ví dụ trên, getVisibilityFilter và getTodos là input-selectors. Chúng được tạo thành như một non-memoized selector functions bởi vì chúng không chuyển đổi dữ liệu chúng chọn. Măt khác, getVisibleTodos là một memoized selector. Nó lấy getVisibilityFilter và getTodos như input-selector, và một hàm biến đổi tính toán danh sách todos đa được lọc

Kết nối Selector với Redux Store

Nếu bạn sử dụng React Redux, Bạn có thể gọi selectors như một function thông thường bên trong mapStateToProps() :

containers/VisibleTodoList.js

import { connect } from 'react-redux'
import { toggleTodo } from '../actions'
import TodoList from '../components/TodoList'
import { getVisibleTodos } from '../selectors'

const mapStateToProps = (state) => {
  return {
    todos: getVisibleTodos(state)
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}

const VisibleTodoList = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList)

export default VisibleTodoList

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. Bài viết này được mình hoàn thành sau khi tham khảo một số tài liệu từ các nguồn:

  • https://spin.atomicobject.com/2017/10/24/react-reselect/
  • https://github.com/reduxjs/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.

0