Day16-Redux 篇-认识 Redux Toolkit

在这篇文章中,我们要来认识一个函式库: Redux Toolkit。

Redux Toolkit 官网

Redux Toolkit 是什麽?

Redux Toolkit 是一个可以帮助你更有效率撰写 Redux 的一个 library,它提供了一些 API 让你更方便的建立 Store、Actions 和 Reducers。

以下介绍几个 API 的作用,在下篇范例中我们将会实际使用它们其中几个。

configureStore()

功用和 createStore 一样可以建立 Store,但还可以结合 reducers、middleware。

范例:

import { configureStore } from '@reduxjs/toolkit'

import rootReducer from './reducers'

const store = configureStore({ reducer: rootReducer })

createAction()

建立 action creator 的函式。放在 createAction() 里面的参数会自动变成 action type,如范例中的 counter/increment,在产生 increment 这个 action creator 之後,将参数带进这个 action creator 会变成 action 的 payload。

范例:

import { createAction } from '@reduxjs/toolkit'

const increment = createAction('counter/increment')

let action = increment()
// { type: 'counter/increment' }

action = increment(3)
// returns { type: 'counter/increment', payload: 3 }

createReducer()

使用它在撰写 reducer 的时候可以不用再用 switch case 语法,并且它的语法底层加入了 immer,因此可以使用会有 side effect 的写法去变更 state,它背後会再帮你转成 「immutable」的方式。

范例:

import { createAction, createReducer } from '@reduxjs/toolkit'

const increment = createAction('counter/increment')
const decrement = createAction('counter/decrement')
const incrementByAmount = createAction('counter/incrementByAmount')

const initialState = { value: 0 }

const counterReducer = createReducer(initialState, (builder) => {
  builder
    .addCase(increment, (state, action) => {
      state.value++
    })
    .addCase(decrement, (state, action) => {
      state.value--
    })
    .addCase(incrementByAmount, (state, action) => {
      state.value += action.payload
    })
})

createSlice()

将一个 slice 的 name、初始化的 state、reducer、action 统一在一个地方建立,并会产生 action creators 和 action type。

import { createSlice } from '@reduxjs/toolkit'

const initialState = { value: 0 }

const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment(state) {
      state.value++
    },
    decrement(state) {
      state.value--
    },
    incrementByAmount(state, action) {
      state.value += action.payload
    },
  },
})

export const { increment, decrement, incrementByAmount } = counterSlice.actions
export default counterSlice.reducer

createAsyncThunk

用来处理非同步,会接受一个 action type 和一个回传 promise 的 callback function,最後回传一个 thunk action creator。

import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
import { userAPI } from './userAPI'

// First, create the thunk
const fetchUserById = createAsyncThunk(
  'users/fetchByIdStatus',
  async (userId, thunkAPI) => {
    const response = await userAPI.fetchById(userId)
    return response.data
  }
)

// Then, handle actions in your reducers:
const usersSlice = createSlice({
  name: 'users',
  initialState: { entities: [], loading: 'idle' },
  reducers: {
    // standard reducer logic, with auto-generated action types per reducer
  },
  extraReducers: (builder) => {
    // Add reducers for additional action types here, and handle loading state as needed
    builder.addCase(fetchUserById.fulfilled, (state, action) => {
      // Add user to the state array
      state.entities.push(action.payload)
    })
  },
})

// Later, dispatch the thunk as needed in the app
dispatch(fetchUserById(123))

下一篇将会针对原本用 Redux 写的程序码范例用 Redux Toolkit 去做改写。


<<:  [Angular] Day30. Angular Module(一)

>>:  Day-29 番外篇:放下笨重的变压器、电源线瘦身计画

Chapter5 - 当一个勤劳的园丁,来修剪我们美丽的树(II)Canvas素材 修图、压缩、效能优化

树叶问题 先前在第三章画树时,就有发现把树叶画上去时,系统工作时间会增加而导致掉侦,原图是300x3...

[想试试看JavaScript ] 讲了好几天的 callback,callback function 是什麽呢?

callback function callback function 也叫回呼函式 Callbac...

[Java Day12] 3.6. break & continue

教材网址 https://coding104.blogspot.com/2021/06/java-b...

Day 28:元件的单元测试

为什麽要做测试? 今天在外面餐厅吃饭,厨师在出菜前会先试吃看看味道对不对;一台咖啡机,在出厂前也会经...

Day 12 Flask 基本设定

开始专案前需要先对 Flask 设定一下,让它能够开发的更顺手(又是一段超短的开头)。 基本设定 刚...