3.4 redux toolkit结合react-redux的使用

参考文档:redux toolkit官网

1.实现

src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { Provider } from 'react-redux'
import {store} from './store'

/**
 * 1.在js入口文件下添加store
 */
ReactDOM.render(
  <Provider store={store}>
    <React.StrictMode>
      <App />
    </React.StrictMode>
  </Provider>,
  document.getElementById('root')
);
reportWebVitals();

store/index.js

import { configureStore } from '@reduxjs/toolkit'
import { hobbySlice } from './slices/hobbyReducer';
import { personSlice } from './slices/personReducer';

/**
 * 2.创建store,其功能对比redux有以下增强
 * 自动组合reducer切片
 * redux-thunk(异步action)中间件默认包含
 * 默认包含并启用 Redux DevTools 扩展
 */
export const store = configureStore({
  reducer: {
    hobby: hobbySlice.reducer,
    person: personSlice.reducer
  }
});

store/slice/hobbyReducer.js

import { createSlice } from '@reduxjs/toolkit'
import { nanoid } from 'nanoid';

/**
 * 3.创建redux切片,以下几点说明
 * redux toolkit默认帮你封装action ,其中的type值是name属性和reducers属性中key的组合,如下面  hobbies/addHobby 和 hobbies/deleteAll
 * 不再需要些大量switch.. case 语句,通过暴露reducers的key,在container里面直接调用方法即可,如有参数传递,通过action接收,action.payload
 * 
 */
export const hobbySlice = createSlice({
  name: 'hobbies',
  initialState: {
    hobbies: [{
      id: nanoid(),
      hobby: '游戏'
    }]
  },
  reducers: {
    addHobby: (state, action) => {
      // state.hobbies = [...state.hobbies, { id: nanoid(), hobby: action.payload }];
      // 在redux里面不能够,在redux tookit可以用push方法
      state.hobbies.push({ id: nanoid(), hobby: action.payload });
    },
    deleteAll: (state) => {
      state.hobbies = [];
    }
  }
})

// 将reducers里面的方法暴露出去,在container容器里面能够使用
export const { addHobby, deleteAll } = hobbySlice.actions;

store/slice/personReducer.js

import { createSlice } from '@reduxjs/toolkit'

export const personSlice = createSlice({
  name: 'person',
  initialState: {
    person: {
      name: "张三",
      age: 18
    }
  },
  reducers: {
    changeName: (state, action) => {
      state.person = { name: action.payload, age: state.person.age }
    }
  }
})

export const { changeName } = personSlice.actions;

store/containers/hobbyContainer.js

import { connect } from "react-redux";
import HobbyUI from "../../components/hobby";
// 引入reducer里面的方法
import { addHobby,deleteAll } from "../slices/hobbyReducer";


const mapStateToProps = (state, ownProps) => {
  return { hobbies: state.hobby.hobbies }
}


const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    addHobby: name => {
      // 注意和以前的却别
      dispatch(addHobby(name))
    },
    deleteAll: () => {
      // 注意和以前的区别,异步逻辑能够实现
      setTimeout(() => {dispatch(deleteAll())}, 1000);
    }
  }
}

/**
 * 4.创建容器,该部分是react-reducer的内容,与以前的差别不大,
 * 唯一区别在于mapDispatchToProps在dispatch是简化了,通过引入reducer切片里面暴露的key直接调用即可
 * 
 */
export const HobbyContainer = connect(
  mapStateToProps,
  mapDispatchToProps
)(HobbyUI)

store/containers/personContainer.js

import { connect } from "react-redux";
import PersonUI from "../../components/person";
import { changeName } from "../slices/personReducer";


const mapStateToProps = (state, ownProps) => {
  return { person: state.person.person }
}


const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    changeName: name => { dispatch(changeName(name)) }
  }
}


export const PersonContainer = connect(
  mapStateToProps,
  mapDispatchToProps
)(PersonUI)

components/hobby/index.js

import React, { Component } from 'react'

/**
 * 5.ui层与以前一样,通过props属性来进行交流,与reducer解耦
 */
export default class HobbyUI extends Component {

  add = name=> {
    this.props.addHobby(name);
  }

  deleteAll = ()=> {
    this.props.deleteAll();
  }

  render() {
    const { hobbies } = this.props;
    const aa = hobbies.map(item => {
      return <li key={item.id}>{item.hobby}</li>
    });
    return (
      <div>
        <ul>
          {aa}
        </ul>
        <div>
          <button onClick={()=>this.add("运动")}>添加</button>
          <button onClick={this.deleteAll}>删除所有</button>
        </div>
      </div>
    )
  }
}

components/person/index.js

import React, { Component } from 'react'

export default class PersonUI extends Component {

  changeName = () => {
    this.props.changeName("王五");
  }

  render() {
    const { person } = this.props
    return (
      <div>
        <span>
          {person.name}----{person.age}
        </span>
        <div>
          <button onClick={this.changeName}>修改姓名</button>
        </div>
      </div>
    )
  }
}

2.redux toolkit对比redux的好处

  • configureStore(): 包装createStore()以提供简化的配置选项和良好的默认值。它可以自动组合slice reducer;能够添加任何 Redux 中间件,默认包含redux-thunk和Redux DevTools中间件,Redux DevTools默认启用
  • createReducer():这使您可以为 case reducer 函数提供操作类型的查找表,而不是编写 switch 语句。此外,它会自动使用该immer库让您使用普通的可变代码编写更简单的不可变更新不可变更新含义参考此处
  • createAction(): 为给定的动作类型字符串生成动作创建器函数(默认封装action)
  • createAsyncThunk: 能够实现异步逻辑。
  • createSlice(): 接受一个reducer函数的对象,一个切片名称,一个初始状态值,并自动生成一个带有相应动作创建者和动作类型的切片reducer。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值