Redux Toolkit

Redux Toolkit

在认识redux-tookit 之前我们回顾一下react-redux

React-Redux

  • 安装

npm i react react-redux -D

yarn add react react-redux -D

  • 创建模板文件 types
    Redux Toolkit_第1张图片

  • 创建 actions

Redux Toolkit_第2张图片

  • 创建 reducers

Redux Toolkit_第3张图片

  • 创建 store
    Redux Toolkit_第4张图片

  • 将Redux连接到React

Redux Toolkit_第5张图片

  • 在React中使用

​ 由于在UI组件中不能使用任何redux的api 所以有以下的两个方法

react-redux 7.1 之前我们通常使用 容器组件与ui组件整合的方法

import React, { useRef } from 'react'

//引入action
import {
    decrement,
    increment,
    incrementAsync
} from '../../redux/actions/count'

//引入connect用于连接UI组件于redux
import { connect } from 'react-redux'


//组件
function Count(props) {
  const selectNumber = useRef(null)
  //加法
  function increment (){
    const {value} = selectNumber.current
    props.increment(value*1)
  }
  //减法
  function decrement (){
    const {value} = selectNumber.current
    props.decrement(value*1)
  }
  //奇数加法
  function incrementIfOdd (){
    const {value} = selectNumber.current
    if(props.count%2 !==0){
      props.increment(value*1)
    }
    
  }
  //异步加法
  function decrementAsync (){
    const {value} = selectNumber.current
    props.incrementAsync(value*1,500)
  }
  return (
    <div> 
        <h1>我是Count组件,下面组件的人数{props.personCount.length}</h1>
        <h3>当前求和为:{props.count}</h3>
        <select ref={selectNumber}>
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
        <br />
        <button onClick={increment}>+</button>&nbsp;&nbsp;
        <button onClick={decrement}>-</button>
        <br />
        <button onClick={incrementIfOdd}>当前求和为奇数再加</button>&nbsp;&nbsp;
        <button onClick={decrementAsync}>异步加</button>
    </div>
  )
}

//调用connect函数 返回值接着调用 返回一个组件 并暴露这个组件
export default connect(
    //映射状态
    state => ({ 
      count: state.count ,
      personCount: state.persons
    }),
    //映射操作状态的方法
    {
        increment,
        decrement,
        incrementAsync
    }
)(Count)

react-redux 7.1之后

import React from 'react';
//引入action
import {
  decrement,
  increment,
  incrementAsync
} from '../../redux/actions/count';
import { useDispatch, useSelector } from 'react-redux'


//组件
function Count() {
  const selectNumber = useRef(null)
  const count = useSelector(state => state.count)
  const personCount = useSelector(state => state.persons)
  const dispatch = useDispatch()
  //加法
  function increment() {
    const { value } = selectNumber.current
    dispatch(increment(value * 1))
  }
  //减法
  function decrement() {
    const { value } = selectNumber.current
    dispatch(decrement(value * 1))
  }
  //奇数加法
  function incrementIfOdd() {
    const { value } = selectNumber.current
    if (count % 2 !== 0) {
      dispatch(increment(value * 1))
    }

  }
  //异步加法
  function decrementAsync() {
    const { value } = selectNumber.current
    dispatch(incrementAsync(value * 1, 500))
  }
  return (
    <div>
      <h1>我是Count组件,下面组件的人数{personCount.length}</h1>
      <h3>当前求和为:{count}</h3>
      <select ref={selectNumber}>
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
      </select>
      <br />
      <button onClick={increment}>+</button>&nbsp;&nbsp;
      <button onClick={decrement}>-</button>
      <br />
      <button onClick={incrementIfOdd}>当前求和为奇数再加</button>&nbsp;&nbsp;
      <button onClick={decrementAsync}>异步加</button>
    </div>
  )
}

export default Count

Redux Toolkit

  • 安装

npm install @reduxjs/toolkit react-redux

  • 创建 slices

​ 现在的slices,就相当于以前的types、actions、reducers,以对象的形式存在。

​ 并且我们不用再返回新state了,我们可以直接操作state,它自己内部实现了immutable的功能

// 引入 createSlice 用于创建 sclices
import { createSlice,createAsyncThunk } from '@reduxjs/toolkit';

// 创建初始值 objects
const objects= [
    {
        id: '001',
        title: '测试第一',
        flage:false
    },
    {
        id: '002',
        title: '测试第二',
        flage:false
    }, {
        id: '003',
        title: '测试第三',
        flage:false
    }
]
// 创建初始值 content
const content = [
]

//异步操作内容
export const conuntasync = createAsyncThunk(
    "user/thunk",
    async (payload:number) => {
        //这里使用fetch请求
        const res = await fetch(
          `http://192.168.210.32:9527/api/goodlist?page=${payload}`
        );
        const response = await res.json();
        return response;
    }
)

const todo = createSlice({
    //起一个名字 随便起,还是建议要有意义
    name: 'todolice',
    //与 之前 reducers 的第一参数一样 定义初始值 和 保存上一次的值
    initialState: {
        objects,
        content
    },
    //定义方法 就是reducers的swicth case 内的操作
    reducers: {
        //每一个方法都有两个参数 
        //state 是 代理对象(Proxy)它的属性里有你定义的 对象 objects,content
        //action 是 接收的值 就是你调用时传的值 后面会讲如何调用
        add: (state, action) => {
            if  (action.payload.title === '')  alert('内容不能为空')
            else state.objects.push(action.payload)
        },
        remove: (state, action) => {
            let arrs = state.objects.filter((item) => {
                return item.id !== action.payload.id
            })
            state.objects = arrs
        }
    },
    //这块内容不是很好理解 但是我平常只是使用它异步调用 仅此
    //官方文档
    //https://redux-toolkit.js.org/api/createSlice#the-extrareducers-builder-callback-notation
    //把异步的执行过程写这里,是与store建立连接
    extraReducers(builder){
        builder
        //conuntasync.pending 上面我们定义的 conuntasync的promise
        //回调函数中第一个参数与reducers中一样,第二个值是异步得到的值
        .addCase(conuntasync.pending, (state) => {
          console.log("pending!")
        })
        .addCase(conuntasync.fulfilled, (state, {payload}) => {
          console.log("fulfilled!", payload);
          state.content = [...payload,...state.content] 
        })
        .addCase(conuntasync.rejected, (state, err) => {
          console.log("rejected!", err)
        });
    }
})

// 相当于以前的actions
export const { incremented, decremented, add } = todo.actions;

// 相当于以前的reducers
export default todo.reducer;
  • 创建store
import { configureStore } from "@reduxjs/toolkit";
import counterSlice from "./slices/counterSlice";
const store = configureStore({
  reducer: {
      //这里用来汇总所有的slices  name:value 类型 
      //value是 slices 
      //每一个slices 都要在这里建立一个 name:value 类型 
    todolice: todo
  },
});

export default store;
  • 将Redux连接到React

​ 这里与react-redux一样

  • 在React组件中使用

​ 也是与react-redux 一样 不过建议使用 react-redux 内置hooks (useDispatch, useSelector)

使用useDispatch —> const dispatch = useDispatch()

使用useSelector —> 1. const objects = useSelector((state)=>{state.todolice.objects })

​ 2.const content= useSelector((state)=>{state.todolice.content})

大概的后面的使用上面已经写过了

总结

react-redux的使用

  1. 安装
  2. 创建types
  3. 创建actions
  4. 创建reducers
  5. 创建store
  6. 将Redux连接到React
  7. 在React中使用

react toolkit的使用

  1. 安装
  2. 创建slices
  3. 创建store
  4. 将Redux连接到React
  5. 在React中使用

2-3步的文件创建流程

store
    ├── slices
    │   ├── todo.js
    │   └── ...
    └── index.js  -->store

Redux Toolkit优点:

  1. Redux Toolkit已经集成了redux-devtools-extension,不需要额外配置,非常方便。
  2. Redux Toolkit已经集成了immutable-js的功能,不需要我们额外安装配置使用,大大提升了开发效率。
  3. Redux Toolkit已经集成了redux-thunk的功能,不需要我们额外安装配置使用,大大提升了开发效率。
  4. Redux Toolkittypes、actions、reducers放在了一起组成全新的slices一目了然简单易懂,简化了我们的使用。

你可能感兴趣的:(javascript,前端,react.js)