react【五】redux/reduxToolkit/手写connext

这篇具有很好参考价值的文章主要介绍了react【五】redux/reduxToolkit/手写connext。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、回顾纯函数

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript
react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript
react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

2、redux

2.1 redux的基本使用

  • pm install redux --save
  • react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript
  • store
const { createStore } = require("redux");

// 1.state数据
const initialState = {
  name: "kiki",
  age: "18",
};

// 2.reducer纯函数
function reducer() {
  return initialState;
}

// 3.创建store
const store = createStore(reducer);

module.exports = store;

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

2.2 通过action修改store的数值

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

const { createStore } = require("redux");
const { ADD_NUMBER, CHANGE_NAME } = require("./constants");

// 1.state数据
const initialState = {
  name: "kiki",
  num: 18,
};

// 2.reducer纯函数

// 两个参数
// 参数1:store目前保存的state 设置默认参数
// 参数2:本次需要更新的action
// 返回值 他的返回值作为之后存储在store的数值 因为第一次调用没有数值 所以设置默认值
function reducer(state = initialState, action) {
  console.log(state, action); // { name: 'kiki', num: '18' } { type: '@@redux/INIT0.n.r.y.w.j' }

  switch (action.type) {
    case ADD_NUMBER:
      // 这里需要创建新的对象的返回 否则页面发现state没有发生变化不会更新界面
      return { ...state, num: state.num + action.num };

    case CHANGE_NAME:
      return { ...state, name: action.name };
    default:
      return state;
  }
}

// 3.创建store
const store = createStore(reducer);

module.exports = store;

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

2.3 订阅state的变化

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

2.4 目录结构

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript
react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

2.5 Redux的使用过程

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

2.6 redux的三大原则

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

2.7 Redux官方图

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

3、redux在React中的使用

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

4、react-redux使用

yarn add react-redux

4.1 react-redux的基本使用

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

import React, { PureComponent } from "react";
import { connect } from "react-redux";
// import store from "../store"
import { addNumberAction, subNumberAction } from "../store/actionCreators";

export class About extends PureComponent {
  calcNumber(num, isAdd) {
    if (isAdd) {
      console.log("加", num);
      this.props.addNumber(num);
    } else {
      console.log("减", num);
      this.props.subNumber(num);
    }
  }

  render() {
    const { counter, banners, recommends } = this.props;

    return (
      <div>
        <h2>About Page: {counter}</h2>
        <div>
          <button onClick={(e) => this.calcNumber(6, true)}>+6</button>
          <button onClick={(e) => this.calcNumber(88, true)}>+88</button>
          <button onClick={(e) => this.calcNumber(6, false)}>-6</button>
          <button onClick={(e) => this.calcNumber(88, false)}>-88</button>
        </div>
      </div>
    );
  }
}

// connect()返回值是一个高阶组件
// function mapStateToProps(state) {
//   return {
//     counter: state.counter
//   }
// }

// function fn2(dispatch) {
//   return {
//     addNumber(num) {
//       dispatch(addNumberAction(num))
//     },
//     subNumber(num) {
//       dispatch(subNumberAction(num))
//     }
//   }
// }

const mapStateToProps = (state) => ({
  counter: state.counter,
  banners: state.banners,
  recommends: state.recommends,
});

const mapDispatchToProps = (dispatch) => ({
  addNumber(num) {
    dispatch(addNumberAction(num));
  },
  subNumber(num) {
    dispatch(subNumberAction(num));
  },
});

// connect是高阶组件
export default connect(mapStateToProps, mapDispatchToProps)(About);

4.2 异步请求 redux-thunk

yarn add redux-thunk
react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript
react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript
react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

4.3 对redux代码结构进行优化 和 redux-devtools

每个页面可能都会有自己的store为了方便维护,将store按照页面划分
react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript
react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

import { createStore, applyMiddleware, compose, combineReducers } from "redux";
import thunk from "redux-thunk";

import counterReducer from "./counter";
import homeReducer from "./home";
import userReducer from "./user";

// 正常情况下 store.dispatch(object)
// 想要派发函数 store.dispatch(function)

// 将两个reducer合并在一起
const reducer = combineReducers({
  counter: counterReducer,
  home: homeReducer,
  user: userReducer,
});

// combineReducers实现原理(了解)
// function reducer(state = {}, action) {
//   // 返回一个对象, store的state
//   return {
//     counter: counterReducer(state.counter, action),
//     home: homeReducer(state.home, action),
//     user: userReducer(state.user, action)
//   }
// }

// redux-devtools
// trace的功能是可以追踪源码
const composeEnhancers =
  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ trace: true }) || compose;

// thunk 是用来发送异步请求的增强写法
const store = createStore(reducer, composeEnhancers(applyMiddleware(thunk)));

export default store;

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

5、ReduxToolkit

5.1 基本使用

npm install @reduxjs/toolkit react-redux
react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript
react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript
react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript
react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

  • 需要在根组件传递store的值
    react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript
    react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript
    react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript
import React, { PureComponent } from "react";
import { connect } from "react-redux";
import { changeNumber } from "../store/features/counter";

export class About extends PureComponent {
  changeNum(num) {
    this.props.changeNumber(num);
  }
  render() {
    const { counter } = this.props;
    return (
      <div>
        {counter}
        <button onClick={(e) => this.changeNum(5)}>+5</button>
      </div>
    );
  }
}

const mapStateToProps = (state) => ({
  counter: state.counter.counter,
});

const mapDispatchToProps = (dispatch) => ({
  changeNumber(num) {
    dispatch(changeNumber(num));
  },
});

export default connect(mapStateToProps, mapDispatchToProps)(About);

5.2 异步操作 写法1

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

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

// toolkit已经集成了thunk所以可以直接使用
// 第一个参数是name可以根据自己的喜好取
// 可以把这个函数看成是promise 它跟promise十分相似
export const fetchHomeMultidataAction = createAsyncThunk(
  "fetch/homemultidata",

  // dispatch传递的参数是第一个 extraInfo
  async (extraInfo, { dispatch, getState }) => {
    console.log(extraInfo);
    const res = await axios.get("http://123.207.32.32:8000/home/multidata");

    // 不能直接返回res 没办法直接对其进行序列化
    return res.data;
  }
);

const homeSlice = createSlice({
  name: "home",
  initialState: {
    banner: [],
  },
  reducers: {
    changeBanner(state, { payload }) {
      state.banner = payload;
    },
  },

  // 这里是对异步操作进行操作的方法
  extraReducers: {
    [fetchHomeMultidataAction.pending](state, action) {
      console.log(action);
    },
    [fetchHomeMultidataAction.fulfilled](state, { payload, meta }) {
      // 异步操作返回的参数
      state.banner = payload.data.banner.list;
      // 在dispatch时传递的参数
      console.log(meta.arg);
    },
    [fetchHomeMultidataAction.rejected](state, action) {
      console.log("fetchHomeMultidataAction rejected");
    },
  },
});

export const { changeBanner } = homeSlice.actions;
export default homeSlice.reducer;

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

5.3 异步操作 写法2

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

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

// toolkit已经集成了thunk所以可以直接使用
// 第一个参数是name可以根据自己的喜好取
// 可以把这个函数看成是promise 它跟promise十分相似
export const fetchHomeMultidataAction = createAsyncThunk(
  "fetch/homemultidata",

  // dispatch传递的参数是第一个 extraInfo
  async (extraInfo, { dispatch, getState }) => {
    console.log(extraInfo);
    const res = await axios.get("http://123.207.32.32:8000/home/multidata");

    // 不能直接返回res 没办法直接对其进行序列化
    return res.data;
  }
);

const homeSlice = createSlice({
  name: "home",
  initialState: {
    banner: [],
  },
  reducers: {
    changeBanner(state, { payload }) {
      state.banner = payload;
    },
  },

  // 这里是对异步操作进行操作的方法
  // extraReducers: {
  //   [fetchHomeMultidataAction.pending](state, action) {
  //     console.log(action);
  //   },
  //   [fetchHomeMultidataAction.fulfilled](state, { payload, meta }) {
  //     // 异步操作返回的参数
  //     state.banner = payload.data.banner.list;
  //     // 在dispatch时传递的参数
  //     console.log(meta.arg);
  //   },
  //   [fetchHomeMultidataAction.rejected](state, action) {
  //     console.log("fetchHomeMultidataAction rejected");
  //   },
  // },
  extraReducers: (builder) => {
    builder
      .addCase(fetchHomeMultidataAction.pending, (state, action) => {
        console.log("fetchHomeMultidataAction pending");
      })
      .addCase(fetchHomeMultidataAction.fulfilled, (state, { payload }) => {
        state.banners = payload.data.banner.list;
        state.recommends = payload.data.recommend.list;
      });
  },
});

export const { changeBanner } = homeSlice.actions;
export default homeSlice.reducer;

6、手写connext

// connect的参数:
// 参数一: 函数
// 参数二: 函数
// 返回值: 函数 => 高阶组件

import { PureComponent } from "react";
import { StoreContext } from "./StoreContext";
// import store from "../store"

//  实际上就是一个高阶函数里面嵌套一个高阶组件
export function connect(mapStateToProps, mapDispatchToProps, store) {
  // 高阶组件: 函数
  return function (WrapperComponent) {
    class NewComponent extends PureComponent {
      //  接收的第二个参数就是context
      constructor(props, context) {
        super(props);

        this.state = mapStateToProps(context.getState());
      }

      componentDidMount() {
        // 因为页面发生改变是connect自己内部实现的 我们自己手写的话 要手动调用
        this.unsubscribe = this.context.subscribe(() => {
          // 不能直接通过强制刷新 不然性能很低
          // this.forceUpdate()

          // 执行ToProps的方法 自己判断是否state发生了变化
          this.setState(mapStateToProps(this.context.getState()));
        });
      }

      componentWillUnmount() {
        this.unsubscribe();
      }

      render() {
        // 传递进来的两个方法进行调用 再把他们的数值传递给组件 实现了高阶组件的增强
        const stateObj = mapStateToProps(this.context.getState());
        const dispatchObj = mapDispatchToProps(this.context.dispatch);
        return (
          <WrapperComponent {...this.props} {...stateObj} {...dispatchObj} />
        );
      }
    }

    // 为了避免每次store都是需要传入进来 所以创建了一个context 在注册应用的时候就将他导入
    NewComponent.contextType = StoreContext;

    return NewComponent;
  };
}

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript
react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

7、合并中间件

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript
react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript
react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript
react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript
react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript
react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript

8、React中的state如何管理

react【五】redux/reduxToolkit/手写connext,react,react.js,前端,javascript文章来源地址https://www.toymoban.com/news/detail-827752.html

到了这里,关于react【五】redux/reduxToolkit/手写connext的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【前端知识】React 基础巩固(三十二)——Redux的三大原则、使用流程及实践

    单一数据源 整个应用程序的state被存储在一颗object tree 中,并且这个object tree 只存储在一个store中; Redux并没有强制让我们不能创建多个Store,但是那样做不利于数据维护; 单一的数据源可以让整个应用程序的state变得方便维护、追踪、修改; State是只读的 唯一修改State的方法

    2024年02月15日
    浏览(60)
  • 【前端知识】React 基础巩固(三十一)——store数据的订阅和Redux的优化

    store/index.js test.js redux代码优化: 将派发的action生成过程放到一个actionCreators函数中 将定义的所有actionCreators的函数,放到一个独立的文件中:actionCreators.js actionCreators 和 reducer 函数中使用字符串常量是一致的,所以将常量抽取到一个独立的constants.js文件中 将reducer和默认值(

    2024年02月15日
    浏览(47)
  • React中使用Redux (二) - 通过react-redux库连接React和Redux

    react-redux库使用Redux 上一篇文章演示React中直接使用Redux的使用过程是十分繁琐的, 并且有许多重复代码 但是实际上redux官方帮助我们提供了 react-redux 的库,这个库是帮助我们完成连接redux和react的辅助工具, 可以直接在项目中使用,并且实现的逻辑会更加的严谨和高效 这篇我们

    2024年02月20日
    浏览(52)
  • 【React】redux和React-redux

    🎀个人主页:努力学习前端知识的小羊 感谢你们的支持:收藏🎄 点赞🍬 加关注🪐 redux 适用于多交互、多数据源的场景。 使用redux的场景: 某个组件的状态需要共享 一个组件需要改变其他组件的状态时 一个组件需要改变全局的状态时 redux的三大原则: 整个应用的 state

    2024年02月06日
    浏览(56)
  • React中使用Redux (一) - 在React中直接使用Redux

    开始之前需要强调一下,redux和react没有直接的关系,你完全可以在React, Angular, Ember, jQuery, or vanilla JavaScript中使用Redux 。 尽管这样说,redux依然是和React库结合的更好,因为他们是通过state函数来描述界面的状态,Redux可以发射状态的更新, 让他们作出相应; 目前redux在react中使

    2024年01月23日
    浏览(58)
  • 前端常见面试题之js基础(手写深拷贝、原型和原型链、作用域和闭包)

    值类型包括 :字符串(string)、数字(number)、布尔值(boolean)、undefined。 引用类型包括 :对象(object)、数组(array)、函数(function)和null。 二者的区别 当你将一个值类型赋给另一个变量时,会复制该值的副本。而当你将一个引用类型赋给另一个变量时,只会复制对

    2024年01月22日
    浏览(47)
  • 在react中使用redux && react-redux的使用demo

    前言: redux是一种状态管理工具,可以存储和操作一些全局或者很多组件需要使用的公共数据。 平心而论,redux的使用对于新上手来说不太友好,多个依赖包的,多种api的结合使用,相对来说比做同样一件事的vuex用起来比较麻烦.不过,熟能生巧,用多了也就习惯了,下面是个人的一个d

    2024年02月06日
    浏览(54)
  • 【React】React——redux

    🚩🚩🚩 💎个人主页: 阿选不出来 💨💨💨 💎个人简介: 一名大二在校生,学习方向前端,不定时更新自己学习道路上的一些笔记. 💨💨💨 💎目前开发的专栏: JS 🍭Vue🍭React🍭 💨💨💨 Redux 是 JavaScript 状态容器,提供可预测化的状态管理。 redux是什么 redux是一个专门用于

    2024年01月15日
    浏览(47)
  • 什么是redux?如何在react 项目中使用redux?

    redux是一种用于管理JavaScript应用程序的状态管理库。它可以与React、Augular、Vue等前端框架结合使用,但也可以纯在JavaScript应用程序中独立使用。redux遵循单项数据流的原则,通过一个全局的状态树来管理应用程序的状态,从而使状态的变化更加可预测和已于维护。 redux的核心

    2024年02月15日
    浏览(38)
  • 【React】React中编写CSS,Redux

    ❤️ Author: 老九 ☕️ 个人博客:老九的CSDN博客 🙏 个人名言:不可控之事 乐观面对 😍 系列专栏: style接受一个采用小驼峰命名属性的JS对象,而不是CSS字符串,可以动态获取当前state中的状态 缺点:1.写法上面需要使用驼峰2.编写样式没有提示3.大量的样式,代码混乱4

    2024年02月09日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包