首页 > 其他分享 >React中使用react-redux、@reduxjs/toolkit状态管理工具

React中使用react-redux、@reduxjs/toolkit状态管理工具

时间:2022-10-04 14:14:11浏览次数:76  
标签:reduxjs toolkit dic react state export import store

react-redux,@reduxjs/toolkit

  • react-redux 是的官方 React UI 绑定层,它允许您的 React 组件从 Redux 存储中读取数据,并将操作分派到存储以更新状态。

React Redux 8.x 需要 React 16.8.3 或更高版本 / React Native 0.59 或更高版本,才能使用 React Hook

  • @reduxjs/toolkit 是对 Redux 的二次封装,开箱即用的一个高效的 Redux 开发工具集,使得创建store、更新store等更简单。

快速开始

0、安装

在 create-react-app 应用中使用,此处使用版本:react v18.2.x、react-redux v8.0.x、@reduxjs/toolkit v1.8.x

$ npm i react-redux @reduxjs/toolkit

1、根组件配置store

// 入口 src/index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'

import store from './store'
import { Provider } from 'react-redux'

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Provider store={store}>
    <App />
  </Provider>
);

2、创建Reducer、Action

// src/store/dic.js
import { createSlice } from '@reduxjs/toolkit'
import baseApi from '../api/base'

// 使用createSlice方法创建一个slice。每一个slice里面包含了reducer和actions,实现模块化的封装
export const counterSlice = createSlice({
  // 命名空间
  name: 'dic',
  // state数据的初始值
  initialState: {
    sortList: [
      { label: '食品类', value: '食品类' },
      { label: '服装类', value: '服装类' },
      { label: '日用品类', value: '日用品类' },
    ]
  },
  // 定义的action。由于内置了immutable插件,可以直接使用赋值的方式进行数据的改变
  reducers: {
    changeVal: (state, action) => {
      // 第一个参数 state为当前state中的数据
      // 第二个参数 action为 {payload: [{ label: '家具类', value: '家具类' }], type: "dic/changeVal"}
      // payload 为传过来的新参数值
      // type 为action触发类型
      console.log('changeVal:', JSON.parse(JSON.stringify(state)), state, action)
      state.sortList = action.payload
    }
  },
})

export const { changeVal } = counterSlice.actions

export default counterSlice.reducer

3、创建store

// src/store/index.js
import { configureStore } from '@reduxjs/toolkit'
import dic from './dic'

export default configureStore({
  reducer: {
    dic,
  },
})

4、组件调用

// src/views/Goods.jsx
import { useSelector, useDispatch } from 'react-redux'
import { changeVal } from '@/store/dic'

function Goods (props) {
  const dispatch = useDispatch()
  // 使用state中的数据
  const sortList = useSelector((state) => state.dic.sortList)

  useEffect(() => {
    // 触发store中action以更新数据
    dispatch(changeVal([{ label: '家具类', value: '家具类' }]))
  }, [])

  return (
    <div>
      渲染数据:
      <ul>
        {
          sortList.map(el => (
            <li key={el.value}>{el.label}</li>
          ))
        }
      </ul>
    </div>
  )
}

export default Goods

异步操作

方式1

// src/store/dic.js
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
import baseApi from '../api/base'

export const loadGoods = createAsyncThunk(
  'dic/fetchGoods',
  (data, thunkAPI) => {
    // thunkAPI:一个对象,其中包含通常传递给 Redux thunk 函数的所有参数,以及其他选项(参考:https://redux-toolkit.js.org/api/createAsyncThunk#payloadcreator)
    baseApi.findGoods(data).then(res => {
      thunkAPI.dispatch(setGoods(res.result))
    })
  }
)

export const counterSlice = createSlice({
  name: 'dic',
  initialState: {
    goodsData: [],
  },
  reducers: {
    setGoods: (state, action) => {
      state.goodsData = action.payload
    }
  },
})

export const { setGoods } = counterSlice.actions

export default counterSlice.reducer

方式2

// src/store/dic.js
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
import baseApi from '../api/base'

export const loadGoods2 = createAsyncThunk(
  'dic/fetchGoods2',
  (data, thunkAPI) => {
    return baseApi.findGoods(data).then(res => res.result)
  }
)

export const counterSlice = createSlice({
  name: 'dic',
  initialState: {
    goodsData: [],
  },
  reducers: {},
  extraReducers: {
    // 异步函数成功fulfilled时回调(类似的还有pending等待、rejected拒绝,此处只列举成功态) 
    [loadGoods2.fulfilled](state, action) {
      state.goodsData = action.payload
    },
  }
})

// export const { } = counterSlice.actions

export default counterSlice.reducer

组件调用

// src/views/Goods.jsx

// 省略其它代码...

useEffect(() => {
  dispatch(loadGoods({ name: '香蕉' }))
  dispatch(loadGoods2({ name: '橘子' }))
}, [])

// 省略其它代码...

标签:reduxjs,toolkit,dic,react,state,export,import,store
From: https://www.cnblogs.com/Faith-Yin/p/16753677.html

相关文章

  • 这可能是你需要的React实战技巧
    一、父组件通过Ref调用子组件中的方法这里同时演示使用函数组件和类组件的父子组件如何编写子组件React.forwardRefReact.useImperativeHandlepublic、private、pr......
  • [Typescript + React] Tips: Write your own 'PropsFrom' helper to extract props fr
    Typehelperschangethegamewhenitcomestotypesinyourcodebase.TheyhelpTypeScriptinfermorefromyourcode-andmakeyourtypesalotmorereadable.......
  • React组件复用的技巧
    复用是组件化开发体系的立命之本,可以说组件化的初衷就是为了复用性。但是组件化的复用方式也存在一定的问题,其中拆分粒度就是其中一个绕不开的话题,今天咱们就来讲一讲Rea......
  • React源码解读之任务调度
    前言简单说下为什么React选择函数式组件,主要是class组件比较冗余、生命周期函数写法不友好,骚写法多,functional组件更符合React编程思想等等等。更具体的可以拜读dan大神的b......
  • react的useState源码分析
    前言简单说下为什么React选择函数式组件,主要是class组件比较冗余、生命周期函数写法不友好,骚写法多,functional组件更符合React编程思想等等等。更具体的可以拜读dan大神的b......
  • React循环DOM时为什么需要添加key
    一、React渲染流程和更新流程react渲染流程:jsx->虚拟dom->真实domreact更新流程:props/state改变->render函数重新执行->生成新的虚拟dom树->新旧虚拟dom树进......
  • React的useLayoutEffect和useEffect执行时机有什么不同
    我们先看下React官方文档对这两个hook的介绍,建立个整体认识useEffect(create,deps):该Hook接收一个包含命令式、且可能有副作用代码的函数。在函数组件主体内(这......
  • react.js 实现音乐播放、下一曲、以及删除歌曲(仅播放列表)
    importReact,{Component}from'react';exportdefaultclassMusicextendsComponent{ constructor(props){  super(props);  this.state={ ......
  • 读懂React原理之调和与Fiber
    一引沿Fiber架构是React16中引入的新概念,目的就是解决大型React应用卡顿,React在遍历更新每一个节点的时候都不是用的真实DOM,都是采用虚拟DOM,所以可以理解成fiber就是R......
  • 你要的react+ts最佳实践指南
    本文根据日常开发实践,参考优秀文章、文档,来说说TypeScript是如何较优雅的融入React项目的。温馨提示:日常开发中已全面拥抱函数式组件和ReactHooks,class类组件的写......