Redux详解(二)

1. 认识Redux Toolkit

Redux Toolkit 是官方推荐的编写 Redux 逻辑的方法。
通过传统的redux编写逻辑方式,会造成文件分离过多,逻辑抽离过于繁琐(具体可看上篇文章 Redux详解一),React官方为解决这一问题,推荐使用Redux Toolkit第三方包将redux逻辑聚合到一个文件中实现,解决上面的问题, Redux Toolkit 也成为 “RTK”。
npm install @reduxjs/toolkit
Redux Toolkit的核心API主要是如下几个:
  • configureStore: 包装createStore以提供简化的配置选项和良好的默认值。它可以自动组合你的 slice reducer,添加你提供的任何 Redux 中间件,redux-thunk默认包含,并启用 Redux DevTools Extension。
  • createSlice:  接受 reducer 函数的对象、切片名称和初始状态值,并自动生成切片 reducer ,并带有相应的 actions
  • createAsyncThunk: 
    接受一个动作类型字符串和一个返回承诺的函数,并生成一个pending/fulfilled/rejected基于该承诺分派动作类型的 thunk,相当于对异步操作的reducer处理,例如网络请求。

2. createSlice的使用

createSlice 主要包含如下几个参数:
  • name:用户标记slice的名词;
  • initialState :初始化;
  • reducers :相当于之前的reducer函数;
    const categorySlice = createSlice({
      name: "category",
      initialState: {
        category: "hello world",
        banners: [],
        recommends: []
      },
      reducers: {
        changeCategory(state, action) {
          state.category = action.payload
        }
      }
    })
    
    export const { changeCategory }  = categorySlice.actions
    
    export default categorySlice.reducer

3. store的创建

configureStore 用于创建store对象,常见参数如下:
  • reducer,将slice中的reducer可以组成一个对象传入此处;
  • middleware :可以使用参数,传入其他的中间件;
  • devTools :是否配置devTools工具,默认为true;
import { configureStore } from "@reduxjs/toolkit"

import counterReducer from './features/counter'
import homeReducer from './features/home'
import userInfoReducer from './features/userInfo'
import categoryReducer from './features/category/category'


// react-toolkit工具包使用方式
const store = configureStore({
  reducer: {
    counter: counterReducer,
    home: homeReducer,
    userInfo: userInfoReducer,
    category: categoryReducer
  }
})

export default store

4. Redux Toolkit的异步操作

以往对于redux中的异步操作,通过redux-thunk中间件让dispatch中可以进行异步操作。

Redux Toolkit默认已经给我们继承了Thunk相关的功能:createAsyncThunk
例如:
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"
import axios from "axios"

export const fetchHomeMultidataActions = createAsyncThunk("fetch/homeMultidata", async () => {
  const res = await axios.get('http://123.207.32.32:8000/home/multidata')

  return res.data
})
当createAsyncThunk创建出来的action被dispatch时,会存在三种状态:
  • pendingaction被发出,但是还没有最终的结果;
  • fulfilled :获取到最终的结果(有返回值的结果);
  • rejected :执行过程中有错误或者抛出了异常;

类似于promise, 参考promise的执行状态

Redux Toolkit在createSlice中通过extraReducer参数可以监听这些状态的过程:

import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"
import axios from "axios"

export const fetchHomeMultidataActions = createAsyncThunk("fetch/homeMultidata", async () => {
  const res = await axios.get('http://123.207.32.32:8000/home/multidata')

  return res.data
})

const categorySlice = createSlice({
  name: "category",
  initialState: {
    category: "hello world",
    banners: [],
    recommends: []
  },
  reducers: {
    changeCategory(state, action) {
      state.category = action.payload
    }
  },
  extraReducers: {
    [fetchHomeMultidataActions.pending](state, action) {
      console.log("pending");
    },
    [fetchHomeMultidataActions.fulfilled](state, {payload}) {
      state.banners = payload.data.banner.list
      state.recommends = payload.data.recommend.list
    },
    [fetchHomeMultidataActions.rejected](state, action) {
      console.log("rejected");
    }
  }
})

export const { changeCategory }  = categorySlice.actions

export default categorySlice.reducer
extraReducer还有另外一种写法:链式调用
Redux详解(二)_第1张图片

5. redux Toolkit在react的运用

通过Redux Toolkit创建store,对于store的数据使用,与传统的store数据获取方式一样,Redux Toolkit只是在store的初始化与逻辑编写进行了封装。

category.jsx

import React, { PureComponent } from 'react'
// import { fetchHomeMultidataActions} from '../../store/features/home'
import { changeCategory, fetchHomeMultidataActions } from '../../store/features/category/category'
import { connect } from 'react-redux'

export class Category extends PureComponent {

  componentDidMount() {
    // 抽离axios到redux
    this.props.fetchHomeMultidata()
  }

  changeCategoryName(name) {
    this.props.changeCategory(name)
  }

  render() {
    const { userInfo, category, banners, recommends }  = this.props
    return (
      
Category:

userInfo: name: {userInfo.name} age: {userInfo.age}

category: name: {category}

banners数据:

    { banners.map((item, index) => { return
  • {item.title}
  • }) }

recommends数据:

    { recommends.map((item, index) => { return
  • {item.title}
  • }) }
) } } const mapStateToProps = (state) => ({ userInfo: state.userInfo.userInfo, category: state.category.category, banners: state.category.banners, recommends: state.category.recommends }) const mapDispatchToProps = (dispatch) => ({ // changeBanners(banners) { // dispatch(changeBannersActions(banners)) // }, // changeRecommends(recommends) { // dispatch(changeRecommendsActions(recommends)) // } fetchHomeMultidata() { dispatch(fetchHomeMultidataActions()) }, changeCategory(name) { dispatch(changeCategory(name)) } }) export default connect(mapStateToProps, mapDispatchToProps)(Category)
Redux详解(二)_第2张图片

你可能感兴趣的:(React学习记录,前端,javascript,开发语言)