ces

发布时间 2023-05-09 07:49:53作者: wanglei1900

Redux Toolkit(RTK)

一、安装

@reduxjs/toolkit依赖于eact-redux库,react-redux 包依赖于@types/react-redux, 因此类型定义将与库一起自动安装。

yarn add react-redux @reduxjs/toolkit

yarn add @types/react-redux -D

二、configureStore

configureStore

根据Redux官方文档,使用useSelector钩子时,如果selector函数只有一个参数state,则可以直接省略传入参数,因为useSelector会自动将state作为参数传入selector函数中。而如果selector函数有多个参数,则需要手动传入所有参数。

reducers 函数里 使用prepare函数来修改传入的action

extraReducers

有时 slice 的 reducer 需要响应 没有 定义到该 slice 的 reducers 字段中的 action。这个时候就需要使用 slice 中的 extraReducers 字段。

extraReducers 一个用途是用来书写多个reducer重复部分,将他们整理共享化,解决冗余问题。甚至可以使用其他slice下的action,另一个是用途是监听createAsyncThunk返回的状态机。

  • builder.addCase(actionCreator, reducer):定义一个 case reducer,它响应 RTK action creator 生成或者普通字符串定义的 action。
  • builder.addMatcher(matcher, reducer):定义一个 case reducer,它可以响应任何 matcher 函数返回 true 的 action.
  • builder.addDefaultCase(reducer):定义一个 case reducer,如果没有其他 case reducer 被执行,这个 action 就会运行。

你可以将这些链接在一起,例如builder.addCase().addCase().addMatcher().addDefaultCase()。 如果多个匹配器匹配操作,它们将按照定义的顺序运行。

在 Redux Toolkit 中,createAsyncThunk 函数返回的是一个带有状态机的 thunk action。这个 thunk action 会 dispatch "pending"、"fulfilled" 和 "rejected" 三种 action 类型,分别对应异步操作的三种状态。在 extraReducers 中,我们可以监听这三种 action 类型,并在相应的 reducer 中更新 state。

在这个例子中,我们使用了 createAsyncThunk 函数创建了一个名为 "posts/fetchPosts" 的异步 thunk action。在 extraReducers 中,我们监听了这个 thunk action dispatch 的 "pending"、"fulfilled" 和 "rejected" 三种 action 类型,并在相应的 reducer 中更新了 state。在 "pending" reducer 中,我们将 state.status 设置为 'loading';在 "fulfilled" reducer 中,我们将 state.status 设置为 'succeeded',并将 action.payload 中的数据添加到 state.posts 数组中;在 "rejected" reducer 中,我们将 state.status 设置为 'failed',并将 action.error.message 存储在 state.error 中。

以下是代码示例:

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

export const fetchPosts = createAsyncThunk('posts/fetchPosts', async () => {
  const response = await client.get('/fakeApi/posts')
  return response.data
})

const postsSlice = createSlice({
  name: 'posts',
  initialState,
  reducers: {
    // omit existing reducers here
  },
  extraReducers(builder) {
    builder
      .addCase(fetchPosts.pending, (state, action) => {
        state.status = 'loading'
      })
      .addCase(fetchPosts.fulfilled, (state, action) => {
        state.status = 'succeeded'
        state.posts = state.posts.concat(action.payload)
      })
      .addCase(fetchPosts.rejected, (state, action) => {
        state.status = 'failed'
        state.error = action.error.message
      })
  }
})

在 Redux Toolkit 中,extraReducers 的 addCase 方法的第一个参数是一个 action creator,用于监听相应的 action 类型。在这个例子中,我们使用了 createAsyncThunk 函数创建了一个名为 "posts/fetchPosts" 的异步 thunk action。在 extraReducers 中,我们监听了这个 thunk action dispatch 的 "pending"、"fulfilled" 和 "rejected" 三种 action 类型,并在相应的 reducer 中更新了 state。

具体来说,我们在 extraReducers 中使用了 builder.addCase 方法来监听 fetchPosts thunk dispatch 的三种 action 类型。在 builder.addCase(fetchPosts.pending, (state, action) => {...}) 中,我们监听了 "pending" action 类型,并在 reducer 中更新了 state.status 的值为 'loading'。在 builder.addCase(fetchPosts.fulfilled, (state, action) => {...}) 中,我们监听了 "fulfilled" action 类型,并在 reducer 中更新了 state.status 的值为 'succeeded',并将 action.payload 中的数据添加到 state.posts 数组中。在 builder.addCase(fetchPosts.rejected, (state, action) => {...}) 中,我们监听了 "rejected" action 类型,并在 reducer 中更新了 state.status 的值为 'failed',并将 action.error.message 存储在 state.error 中。

Redux Toolkit中的addCase方法用于为reducer添加一个新的case。它的第一个参数是一个action类型字符串或一个action creator,第二个参数是一个reducer函数。

在Redux Toolkit中,我们可以使用extraReducers方法来添加额外的reducer。extraReducers方法有两种用法,一种是使用箭头函数作为参数传递给它,另一种是直接调用extraReducers方法并将builder对象作为参数传递给它。

无论是哪种用法,我们都可以使用builder.addCase方法来添加一个新的case。第一个参数可以是一个action类型字符串或一个action creator。如果是一个action creator,它应该返回一个状态机,例如createAsyncThunk返回的状态机。

因此,addCase的第一个参数的区别在于它可以是一个普通的action类型字符串或一个返回状态机的action creator。无论哪种情况,我们都可以使用builder.addCase方法来为reducer添加一个新的case。