IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> React使用redux react-redux redux-thunk -> 正文阅读

[JavaScript知识库]React使用redux react-redux redux-thunk

React redux
[?ri?d?ks]

〇、预备

安装

npm install --save redux
npm install --save react-redux(基础款用不上)
npm install --save redux-thunk
npm install --save-dev redux-devtools(不必要)

一、基础版

已经将reducer和actions抽出

1.仓库文件

// 1.创建仓库对象,解构必要的函数,并引入redux-thunk改装增强redux
import { createStore, combineReducers, applyMiddleware } from "redux";
import thunk from "redux-thunk";

// 8.引入操作模块
import userdata from "./userData/userData";

// 9.将多个Reducers模块合并
let rootReducer = combineReducers({ userdata });

// 2.导出仓库,为了处理异步方便,使用applyMiddleware并把thunk传入使用
export default createStore(rootReducer, applyMiddleware(thunk));

2.reducer文件

// 3.新建抽出reducer的文件。给数据设置默认值,也可以不写,因为找值的时候不是从这里直接去取,而是在函数里面找,函数的参数会拿到这个默认,所以说这不是数据,只是初始值。
let initUserData = {}

// 4.导出这个Reducers操作模块。
// 第一个导出这个函数的第一个参数是state(就是数据),第二个函数是action(操作的动作,以及处理异步数据)
// 可以直接在这里给userdata赋初值,也可以写之前定义好的变量,因为depatch
export default (userdata = initUserData, action) => {
    // 5.从action解构出type和payload,使用时就不用action.type
    const { type, payload } = action
    // 6.每一个操作的type类型,对应一个方法
    switch (type) {
        // 7.给对应的type类型写具体的操作方法
        // case "INITUSERDATA": {
        //     userdata = { ...payload }
        // } return userdata;

        case "INITUSERDATA": return { ...payload };

        // case "ABCDEFG": {
        //     userdata = payload++
        // } return userdata;
    }
    // 没有匹配的action需要返回一个数据,就是初始值
    return userdata
}

3.actions文件

// 12.新建抽出actions操作数据的userData的actions.js文件

// 13.写修改数据的类型,与reducer文件的type类型对应
// inituserdatd是函数名,payload是调用这个函数时传入的参数,type与reducer的type对应,代码会去找他
// inituserdatd函数的返回值是一个json对象
// 这里的导出不能使用default,因为会导出多个
export const inituserdatd = payload => ({
    type: "INITUSERDATA",
    payload
})

4.修改数据的组件

// 10.引入store
import store from "../../store/index.js"

// 14.引入操作数据的actions.js文件
import { inituserdatd } from "../../store/userData/actions"


export default class EPLogin extends React.Component {
                        // 11.获取redux中的值
                        store.getState().UserData

                        // 15.修改数据,dispatch派发一个更改
                        store.dispatch(inituserdatd({ ...data }));
                        // console.log(store);
}

5.根文件

// 18.跟组件引入store文件
import store from "../src/store/index";

ReactDOM.render(
  <>
    <BrowserRouter>
      {/* <React.StrictMode> */}
      <App />
      {/* </React.StrictMode> */}
    </BrowserRouter>
  </>,
  document.getElementById('root')
);

// 19. 在根文件中订阅,避免重复写,省事。
// 但会带来性能问题,因为会重新刷新子组件;尽管有diff算法,但对比也需要性能呢
store.subscribe(render)

6.使用数据的文件

// 16.在另一个组件里引入store文件
import store from "../../store/index.js"

export default class Over extends React.Component {
    componentDidMount() {
        // 17.在另一个组件里获取值
        console.log(store.getState().userdata);
    }
}    

二、react-redux强化版

仓库文件、reducer文件、actions文件不变,只是在使用和更改数据的组件稍有不一样,主要是简化数据修改和订阅的过程。

思路:

  1. 用Provider包裹最顶层的组件,提供一个store属性。这样redux任何组件里都可以使用store了。
  2. 使用connect()函数来链接react的组件和redux的store。记住:connect不能单独使用,必须要有Provider。

1.根文件

// 引入react-redux
import { Provider } from "react-redux";
import store from "../src/store/index";

ReactDOM.render(
  <>
      {/* 用Provider组件包裹住根组件,并在属性中给它传入创建好的store对象 */}
      <Provider store={store}>
        <App />
      </Provider>
  </>,
  document.getElementById('root')
);

2.获取数据的组件

// 引入react-redux并解构出connect函数
import { connect } from "react-redux"

// 不要直接导出组件,需要通过高阶组件,增加属性
class Over extends React.Component {
    componentDidMount() {
        // 使用时,因为通过connect(mapStateToProps)(Over)已经将store挂载在组件的属性上,所以通过读取属性的方法就可以拿到数据
        console.log( this.props.userdata);
    }
}

// 定义mapStateToProps函数,函数中用对象的形式声明需要的数据
const mapStateToProps = (state) => ({
    userdata: state.userdata
})

// connect是一个函数,使用时需要传入一个mapStateToProps函数;调用完之后connect组件的返回值是一个高阶函数,再把使用数据的组件传入,并在此处导出。
export default connect(mapStateToProps)(Over)

3.获取数据,同时修改数据的组件

// 引入操作数据的actions.js文件
import { inituserdatd } from "../../store/userData/actions"
// 引入react-redux并解构出connect函数
import { connect } from "react-redux"

// 不要直接导出组件,需要通过高阶组件,增加属性
class EPLogin extends React.Component {
    
    componentDidMount() {
        // 使用修改数据的方法,通过属性就可以
        this.props.adduserdata({ ...data })
        
        // 使用时,因为通过connect(mapStateToProps)(Over)已经将store挂载在组件的属性上,所以通过读取属性的方法就可以拿到数据
        console.log( this.props.userdata);
        
    }
    
}

// !这些函数不论类组件还是函数组件,都写在他们的外边

// 定义mapStateToProps函数,函数中用对象的形式声明需要的数据。
// 这个函数可以单独定义,也可以直接写在connect中。无所谓的。
const mapStateToProps = (state) => ({
    userdata: state.userdata
})

// 定义mapDispatchToProps函数,函数中用对象的形式就可以获取到操作数据的方法。
const mapDispatchToProps = (dispatch) => ({
    adduserdata: (payload) => dispatch(inituserdatd(payload))
})

// connect是一个函数,使用时需要传入一个mapStateToProps函数;调用完之后connect组件的返回值是一个高阶函数,再把使用数据的组件传入,并在此处导出。
export default connect(mapStateToProps, mapDispatchToProps)(EPLogin)

三、在redux中异步获取数据

思路:在需要数据的组件渲染完成后调用dispatch中的方法,给store一个时机去发送请求,(如果发送请求的代码直接写在store里运行,就会导致需要使用数据的组件会在数据请求回来之前已经完成渲染),在store内请求数据,然后通过actions提交保存给自己,其他组件就可以从组件中store获取。

1.reducer文件

export default (meetcount = 0, action) => {

    const { type, payload } = action
    switch (type) {

        case "CHANGEMEETCOUNT": {
            meetcount = payload
        } return meetcount;

    }

    return meetcount
}

2.actions文件

import { queryMeetdb } from "../../api/meets";
// 异步请求,请求到数据之后dispatch给store获取数据
export const changemeetcount = (payload) => (async dispatch => {
    // 请求已封装
    let count = await queryMeetdb(payload);
    let meetcount = count.data.length
    dispatch({
        type: "CHANGEMEETCOUNT",
        payload: meetcount
    });
})

3.使用数据的组件

import { connect } from "react-redux"
import { inituserdatd } from "../../store/userData/actions"
import { changemeetcount } from "../../store/meetCount/actions"


const AddMeeting = (props) => {
    // 在store中获取员工名,并重新提交在redux重新查询修改store中的数据
    let epnameuse = props.userdata.epname
    props.meetcountchange({ "meetuser": epnameuse })
}


const mapStateToProps = (state) => ({
    userdata: state.userdata,
    meetcount: state.meetcount
})

const mapDispatchToProps = dispatch => ({
    meetcountchange: (payload) => dispatch(changemeetcount(payload)),
    adduserdata: (payload) => dispatch(inituserdatd(payload))
})

export default connect(mapStateToProps, mapDispatchToProps)(AddMeeting)

优化内存可以使用Immutable
详情见后续

感谢你能看完,也感谢我能写完

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章           查看所有文章
加:2021-07-22 14:04:22  更:2021-07-22 14:07:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/6 10:26:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码