Redux toolkit “xịn” như thế nào ?

Giới thiệu Redux là công cụ quản lý state phổ biến trong reactjs nói riêng và trong hệ sinh thái js nói chung (angularjs, vuejs, …). Tuy nhiên, luôn có 1 vài vấn đề khi sử dụng redux đó là: Configuring a Redux store is too complicated. I have to add a lot of packages

Giới thiệu

Redux là công cụ quản lý state phổ biến trong reactjs nói riêng và trong hệ sinh thái js nói chung (angularjs, vuejs, …). Tuy nhiên, luôn có 1 vài vấn đề khi sử dụng redux đó là:

  • Configuring a Redux store is too complicated.
  • I have to add a lot of packages to get Redux to do anything useful.
  • Redux requires too much boilerplate code.

( các bạn tự dịch nha ^^)

Và đó chính là nền tảng để ra đời RTK, từ đây ta có thể tận dụng những lợi ích của redux cũng như giúp viết code redux nhanh gọn, dễ hiểu, hoàn chỉnh theo một quy chuẩn thống nhất.

Bài viết này dành cho những bạn đã sử dụng hay đã biết về redux, còn với những bạn chưa từng sử dụng redux, mình nghĩ rằng các bạn nên tiếp cận với redux cơ bản trước, nắm bắt được cách thức hoạt động cũng như các khái niệm chính như actions, reducer, store…

Mình xin đính chính lại đó là RTK không làm thay đổi cách thức hoạt động của redux. Việc cài đặt cũng vỗ cùng dễ dàng :

Sau khi tạo 1 project bằng lệnh:

npx create-react-app your_app_name  // tạo project
npm i --save  redux react-redux  // cài redux

Ta sẽ sử dụng lệnh sau :

# NPM
npm install @reduxjs/toolkit

# Yarn
yarn add @reduxjs/toolkit

Cơ bản là done rồi đó, cài đặt thì chỉ đơn giản vậy thôi 😃.

RTK bao gồm những gì?

  • Có sẵn Redux DevTools
  • Có sẵn redux-thunk để thực hiện async actions
  • Tự động sử dụng thư viện Immerjs

Một số API hay dùng

1. configureStore()

// Khi chưa có Redux Toolkit thì trong store.js sẽ như thế này

import { createStore, applyMiddleware, compose } from 'redux';
import thunkMiddleware from 'redux-thunk';
import rootReducer from './reducers';// Enable to use redux dev tool in development modeconstcomposeEnhancers='development'=== process.env.NODE_ENV?(window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__||compose):compose;// Use redux-thunk as a redux middlewareconstenhancer=composeEnhancers(applyMiddleware(thunkMiddleware));conststore=createStore(rootReducer,{}, enhancer);
export default store;
// Khi đã có redux toolkit 🤣// thì store.js sẽ :

import { configureStore } from '@reduxjs/toolkit'
import rootReducer from './reducers'// xem mục bên dưới để tạo reducerconststore=configureStore({ reducer: rootReducer })

export default store;// tạo store thật ngắn gọn

2. createReducer()

// Không có Redux ToolkitfunctioncounterReducer(state =0, action){switch(action.type){case'increment':return state + action.payload
        case'decrement':return state - action.payload
        default:return state
    }}

export default counterReducer;
// Có Redux Toolkit// - Mỗi key là một case ứng với 1 action - xem phần createAction()// - Không cần handle default case constcounterReducer=createReducer(0,{
    increment:(state, action)=> state + action.payload,decrement:(state, action)=> state - action.payload
})

export default counterReducer;
// Một điểm hay nữa là reducer có thể mutate data trực tiếp.// Bản chất bên dưới họ sử dụng thư viện ImmerjsconsttodoReducer=createReducer([],{
        addTodo:(state, action)=>{// 1. Có thể mutate data trực tiếp 🎉
            state.push(action.payload)},removeTodo:(state, action)=>{// 2. Hoặc phải trả về state mới// CHỨ KO ĐƯỢC cả 1 và 2 nha 😎constnewState=[...state];
            newState.splice(action.payload,1);return newState;}})

export default todoReducer;

3. createAction()

// Không có redux toolkitconstINCREMENT='increment'functionincrement(amount){return{
    type:INCREMENT,payload: amount
    }}// gọi 1 action trong 1 component nào đó
import { increment } from 'path-to-action-file';
import { useDispatch } from 'react-redux';// cái này trong react hooks nhaconstdispatch=useDispatch();constaction=increment(6)dispatch(action);//action sẽ dispatch đi với thông tin là { type: 'increment', payload: 6 }
// Có redux toolkitconstincrement=createAction('increment')constaction=increment(3)// returns { type: 'increment', payload: 3 }
console.log(increment.toString())// 'increment'

4. createSlice()

Phần này sẽ bao gôm cả 3 phần trên, và mình thường sử dụng createSlice() , vì nó gọn và còn bao gồm cả createReducer()createAction() nữa, ok cùng xem nó sử dụng như thế nào nhé

// trong file tạo reducer ở đâu đó tùy cấu trúc thư mục của bạn 
    import { createSlice } from '@reduxjs/toolkit';constlistCandidate=createSlice({
        name:'candidates',// domain name of action type
        initialState:[],reducers:{
            addCandidate:(state, action)=>{
                state.push(action.payload);},editCandidate:(state, action)=>{// code}}});

    export constcandidateSelector= state => state.candidateList;// có thể export các selector ở đây để tiện sử dụng lạiconst{ reducer, actions }= listCandidate;
    export const{ addCandidate, editCandidate }= actions;
    
    export default reducer;
// trong src/app/store.js
    
    import { configureStore } from '@reduxjs/toolkit';
    import candidateReducer from 'đường dẫn tới file tạo reducer';constrootReducer={
        candidateList: candidateReducer  
        // có thể thêm các reducer khác vào đây và nhớ ngăn cách bằng dấu phẩy}conststore=configureStore({
        reducer: rootReducer
    });

    export default store;

Ok bây giờ ta sẽ đưa thằng store vào Provider để có thể sử dụng ở mọi nơi

// trong file src/index.js
 
    import React from 'react';
    import ReactDOM from 'react-dom';

    import './index.css';
    import App from './App';
    import reportWebVitals from './reportWebVitals';

    import { Provider } from 'react-redux';
    import store from 'app/store';

    ReactDOM.render(<React.StrictMode><Provider store={store}>//đưa store vào đây<App /></Provider></React.StrictMode>,
      document.getElementById('root'));reportWebVitals();

Done, vậy là các bạn đã setup xong cơ bản 1 store sử dụng RTK, bây giờ mọi thay đổi của state thông qua các action sẽ được cập nhật trên store, bạn có thể sử dụng các hook như useDispatch() và useSelector() để thao tác với store (lưu ý nữa là để dùng được hooks thì các bạn phải cài reactjs phiên bản >= 16.8 nha)

Ngoài ra các bạn có thể tìm đọc các api khác:

Và RTK không chỉ giới hạn ở những tính năng trên, nó còn có nhiều cái hay ho nữa mà mình xin phép được chia sẻ nó trong các bài viết sau. Cám ơn mn đã quan tâm.

Nguồn: viblo.asia

Bài viết liên quan

WebP là gì? Hướng dẫn cách để chuyển hình ảnh jpg, png qua webp

WebP là gì? WebP là một định dạng ảnh hiện đại, được phát triển bởi Google

Điểm khác biệt giữa IPv4 và IPv6 là gì?

IPv4 và IPv6 là hai phiên bản của hệ thống địa chỉ Giao thức Internet (IP). IP l

Check nameservers của tên miền xem website trỏ đúng chưa

Tìm hiểu cách check nameservers của tên miền để xác định tên miền đó đang dùn

Mình đang dùng Google Domains để check tên miền hàng ngày

Từ khi thông báo dịch vụ Google Domains bỏ mác Beta, mình mới để ý và bắt đầ