当前位置:   article > 正文

Redux详解(二)

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函数;
    1. const categorySlice = createSlice({
    2. name: "category",
    3. initialState: {
    4. category: "hello world",
    5. banners: [],
    6. recommends: []
    7. },
    8. reducers: {
    9. changeCategory(state, action) {
    10. state.category = action.payload
    11. }
    12. }
    13. })
    14. export const { changeCategory } = categorySlice.actions
    15. export default categorySlice.reducer

3. store的创建

configureStore 用于创建store对象,常见参数如下:
  • reducer,将slice中的reducer可以组成一个对象传入此处;
  • middleware :可以使用参数,传入其他的中间件;
  • devTools :是否配置devTools工具,默认为true;
  1. import { configureStore } from "@reduxjs/toolkit"
  2. import counterReducer from './features/counter'
  3. import homeReducer from './features/home'
  4. import userInfoReducer from './features/userInfo'
  5. import categoryReducer from './features/category/category'
  6. // react-toolkit工具包使用方式
  7. const store = configureStore({
  8. reducer: {
  9. counter: counterReducer,
  10. home: homeReducer,
  11. userInfo: userInfoReducer,
  12. category: categoryReducer
  13. }
  14. })
  15. export default store

4. Redux Toolkit的异步操作

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

Redux Toolkit默认已经给我们继承了Thunk相关的功能:createAsyncThunk
例如:
  1. import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"
  2. import axios from "axios"
  3. export const fetchHomeMultidataActions = createAsyncThunk("fetch/homeMultidata", async () => {
  4. const res = await axios.get('http://123.207.32.32:8000/home/multidata')
  5. return res.data
  6. })
当createAsyncThunk创建出来的action被dispatch时,会存在三种状态:
  • pendingaction被发出,但是还没有最终的结果;
  • fulfilled :获取到最终的结果(有返回值的结果);
  • rejected :执行过程中有错误或者抛出了异常;

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

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

  1. import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"
  2. import axios from "axios"
  3. export const fetchHomeMultidataActions = createAsyncThunk("fetch/homeMultidata", async () => {
  4. const res = await axios.get('http://123.207.32.32:8000/home/multidata')
  5. return res.data
  6. })
  7. const categorySlice = createSlice({
  8. name: "category",
  9. initialState: {
  10. category: "hello world",
  11. banners: [],
  12. recommends: []
  13. },
  14. reducers: {
  15. changeCategory(state, action) {
  16. state.category = action.payload
  17. }
  18. },
  19. extraReducers: {
  20. [fetchHomeMultidataActions.pending](state, action) {
  21. console.log("pending");
  22. },
  23. [fetchHomeMultidataActions.fulfilled](state, {payload}) {
  24. state.banners = payload.data.banner.list
  25. state.recommends = payload.data.recommend.list
  26. },
  27. [fetchHomeMultidataActions.rejected](state, action) {
  28. console.log("rejected");
  29. }
  30. }
  31. })
  32. export const { changeCategory } = categorySlice.actions
  33. export default categorySlice.reducer
extraReducer还有另外一种写法:链式调用

5. redux Toolkit在react的运用

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

category.jsx

  1. import React, { PureComponent } from 'react'
  2. // import { fetchHomeMultidataActions} from '../../store/features/home'
  3. import { changeCategory, fetchHomeMultidataActions } from '../../store/features/category/category'
  4. import { connect } from 'react-redux'
  5. export class Category extends PureComponent {
  6. componentDidMount() {
  7. // 抽离axios到redux
  8. this.props.fetchHomeMultidata()
  9. }
  10. changeCategoryName(name) {
  11. this.props.changeCategory(name)
  12. }
  13. render() {
  14. const { userInfo, category, banners, recommends } = this.props
  15. return (
  16. <div>
  17. Category:
  18. <h2>userInfo: name: {userInfo.name} age: {userInfo.age}</h2>
  19. <h2>category: name: {category}</h2>
  20. <button onClick={ e => this.changeCategoryName('你好 世界')}>修改</button>
  21. <div>
  22. <h2>banners数据:</h2>
  23. <ul>
  24. {
  25. banners.map((item, index) => {
  26. return <li key={index}>{item.title}</li>
  27. })
  28. }
  29. </ul>
  30. </div>
  31. <div>
  32. <h2>recommends数据:</h2>
  33. <ul>
  34. {
  35. recommends.map((item, index) => {
  36. return <li key={index}>{item.title}</li>
  37. })
  38. }
  39. </ul>
  40. </div>
  41. </div>
  42. )
  43. }
  44. }
  45. const mapStateToProps = (state) => ({
  46. userInfo: state.userInfo.userInfo,
  47. category: state.category.category,
  48. banners: state.category.banners,
  49. recommends: state.category.recommends
  50. })
  51. const mapDispatchToProps = (dispatch) => ({
  52. // changeBanners(banners) {
  53. // dispatch(changeBannersActions(banners))
  54. // },
  55. // changeRecommends(recommends) {
  56. // dispatch(changeRecommendsActions(recommends))
  57. // }
  58. fetchHomeMultidata() {
  59. dispatch(fetchHomeMultidataActions())
  60. },
  61. changeCategory(name) {
  62. dispatch(changeCategory(name))
  63. }
  64. })
  65. export default connect(mapStateToProps, mapDispatchToProps)(Category)
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/510825
推荐阅读
相关标签
  

闽ICP备14008679号