在这篇文章中,我们要来认识一个函式库: Redux Toolkit。
Redux Toolkit 是一个可以帮助你更有效率撰写 Redux 的一个 library,它提供了一些 API 让你更方便的建立 Store、Actions 和 Reducers。
以下介绍几个 API 的作用,在下篇范例中我们将会实际使用它们其中几个。
功用和 createStore 一样可以建立 Store,但还可以结合 reducers、middleware。
范例:
import { configureStore } from '@reduxjs/toolkit'
import rootReducer from './reducers'
const store = configureStore({ reducer: rootReducer })
建立 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 }
使用它在撰写 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
})
})
将一个 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
用来处理非同步,会接受一个 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 番外篇:放下笨重的变压器、电源线瘦身计画
树叶问题 先前在第三章画树时,就有发现把树叶画上去时,系统工作时间会增加而导致掉侦,原图是300x3...
callback function callback function 也叫回呼函式 Callbac...
教材网址 https://coding104.blogspot.com/2021/06/java-b...
为什麽要做测试? 今天在外面餐厅吃饭,厨师在出菜前会先试吃看看味道对不对;一台咖啡机,在出厂前也会经...
开始专案前需要先对 Flask 设定一下,让它能够开发的更顺手(又是一段超短的开头)。 基本设定 刚...