redux及react-redux

redux

这篇文章谈一谈仓库redux。

首先,学习任何东西都离不开官网。在此附上官网网址

Redux - A predictable state container for JavaScript apps. | Redux

1.什么是redux?

从如下几个方面:

redux在一个项目中可集中管理状态(数据)和逻辑代码,让你开发出强大的功能。

redux一般在中大型项目较为适用,小型项目建议使用订阅发布。

主要用于处理各个组件之间的通信问题。

2.使用redux的三大原则–规范

1.整个应用的数据state,只存放在唯一的store中。

2.state是只读的,唯一改变state数据的方法,是通过action自定义事件去修改。action是一个对象。通过Store.dispatch()去调用。

3.action自定义事件是需要通过纯函数的方式去触发的,因此需要编写与useReducer结构类似的函数去修改。reduce函数有两个参数:

参数一:上一次state的数据

参数二:传递过来的action

reduce函数要返回新的state数据。

3.原理过程分析:

在这里插入图片描述

初始化阶段:

仓库store-视图view(组件)

1.首先使用最顶层的reducer函数,创建redux-store。

​ createStore(callback)接受一个回调函数。这个回调函数就是最顶层的reducer函数

2.store调用一次reducer函数,并将返回值作为最新的state数据

3.与view框架交互,并将state数据渲染到UI视图层上面去,同时监听store的存在,以便知道state的更新

更新阶段

1.用户通过行为触发事件

2.通过store.dispatch()一个action给reducer进行state数据的处理。

3.此时数据虽然更改了,但有一个问题,没有触发视图的更新。有两种解决方案,一种是使用useState中的函数,还有一种就是重新渲染app组件。可能大家会认为非常损耗性能,但diff算法帮我们节省了性能

4.store 通知所有订阅过的 UI,通知它们 store 发生更新每个订阅过 store 数据的 UI 组件都会检查它们需要的 state 部分是否被更新。发现数据被更新的每个组件都强制使用新数据重新渲染,紧接着更新网页

4.使用

安装redux

npm i redux

然后就可以使用了


计数器小demo:

建立redux文件夹

store.js

import { createStore } from 'redux'
import { aa } from './reducers'
export default createStore(aa)

reducers.js

function aa(state = { num: 1 }, actions) {
    console.log(state, actions);
    let num = state.num
    switch (actions.type) {
        case "add":
            num = num + actions.data
            return { num }
        default:
            break;
    }
    return state
}
export {
    aa
}

index.js进行数据监听

// 操作dom
import ReactDOM from "react-dom/client";
// 引入App组件
import App from "./App"
// 引入css文件
import "./app.scss"
import store from "./redux/store"

import { BrowserRouter } from "react-router-dom"
// 设置挂载位置
const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(
    <App />
)
store.subscribe(() => {
    root.render(
        <App />
    )
})

5.一个基础完整的redux实例代码

App.js

import React from 'react'
import store from "./redux/store"
import { createAdd, createDel } from './redux/action/createSum'
export default function App() {
    let { num } = store.getState()
    const handleAdd = () => {
        store.dispatch(createAdd())
    }
    const handleDel = () => {
        store.dispatch(createDel())
    }
    return (
        <div>
            <p>数据之{num}</p>
            <button onClick={handleAdd}>Add1</button>
            <button onClick={handleDel}>Del1</button>
        </div>
    )
}

redux/action/createSum.js

export const createAdd = () => {
    return { type: 'add', data: 1 }
}
export const createDel = () => {
    return { type: 'del', data: 1 }
}

redux/store.js

import { createStore } from 'redux'
import { aa } from './reducer/reducers'
export default createStore(aa)

redux/reducer/reducers.js

let init = { num: 1 }
function aa(state = init, actions) {
    console.log(state, actions);
    //由于纯函数的规范,返回是新的值
    let newState = { ...state }


    switch (actions.type) {
        case "add":
            newState.num = newState.num + actions.data
            return newState
        case "del":
            newState.num -= actions.data
        default:
            break;
    }
    return newState
}
export {
    aa
}

6.redux store里面处理异步

需要引入插件 redux-thunk

在store.js中引入

import { createStore, applyMiddleware } from 'redux'
import { aa } from './reducer/reducers'
import reduxThunk from 'redux-thunk'
export default createStore(aa, applyMiddleware(reduxThunk))

7.react-redux

小分类?

react-redux 旧版本 函数与class都通用

react-toolkit hooks版本,函数用的

什么是react-redux?

​ redux是一个独立的仓库,可以和市面上流行的框架例如Vue,angular,react等ui框架结合一起使用。如果我们要同时使用react和redux的时候,我们建议不要直接把react组件内容和store进行交互,而是应该将react-redux作为中间桥梁连接其中。

在这里插入图片描述

  1. 容器组件 包裹 UI组件 通过容器组件 与 redux进行操作
  2. 容器组件操作仓库 仓库数据给容器组件, 容器组件将数据给UI组件
  3. UI组件触发 容器组件发送action 给仓库进行修改数据

使用:

安装

npm i react-redux

初始版本:

components/SumUI

import React from 'react'
import store from "../redux/store"
import { createAdd, createDel, createAsync } from '../redux/action/createSum'
export default function SumUI(props) {
    console.log(props);
    let num = props.num
    const handleAdd = () => {
        props.handleAdd()
    }
    const handleDel = () => {
        props.handleDel()
    }
    const handleAsync = () => {
        props.handleAsync()
    }
    return (
        <div>
            <p>数据之{num}</p>
            <button onClick={handleAdd}>Add1</button>
            <button onClick={handleDel}>Del1</button>
            <button onClick={handleAsync}>异步加</button>
        </div>
    )
}

containner/Sum

import { connect } from 'react-redux'
import SumUI from '../component/SumUI'
import { createAdd, createDel, createAsync } from '../redux/action/createSum'
function mapStateToProps(state) {
    return state
}
const mapDispatchToProps = (dispatch) => {

    return {
        handleAdd: () => dispatch(createAdd()),
        handleDel: () => dispatch(createDel()),
        handleAsync: () => dispatch(createAsync())
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(SumUI)

App.js

import React from 'react'
import Sum from './container/Sum'
import store from './redux/store'
export default function App() {
    return (
        <div>
            <Sum store={store}></Sum>
        </div>
    )
}

优化点:

1.mapStateToProps直接在connect里面写回调函数

2.mapDispatchToProps可以写成对象形式。系统会自动用dispatch包裹。

Sum.jsx优化

import { connect } from 'react-redux'
import SumUI from '../component/SumUI'
import { createAdd, createDel, createAsync } from '../redux/action/createSum'


export default connect(state => state, {
    handleAdd: createAdd,
    handleDel: createDel,
    handleAsync: createAsync
})(SumUI)

8.多组件之间通信

关键api:combineReducer

9.使用redux-devtools

如果要使用redux-devtools,我们需要使用第三方插件

安装 redux-devtools-extension,然后在store.js中配置

import {applyMiddleware, createStore,combineReducers} from "redux"
// 引入stroe异步中间件
import Thunk from "redux-thunk"
// 引入所有的纯函数reduce
import reduce from "./index"
// 使用插件查看数据
import {composeWithDevTools} from "redux-devtools-extension"
// 暴露仓库(store)
export default createStore(reduce,composeWithDevTools(applyMiddleware(Thunk)))

10.react-redux提供自定义的hooks

需要三个 redux react-redux @reduxjs/toolkit

1.创建store redux/store.js

// 开始准备创建仓库
import { configureStore } from '@reduxjs/toolkit';
// 引入纯函数
import reducerSum from "./reducers/reduceSum"


// 返回值就是仓库
const store = configureStore({
    // 每个组件的纯函数
    reducer:{
        reducerSum
    }
})



export default store

2.创建reducer纯函数 reducers/reduceSum.js

// 通过@reduxjs/toolkit创建纯函数
import {createSlice} from "@reduxjs/toolkit"

// 创建纯函数
const  reducerSum =  createSlice({
    name:"reducerSum",  // 名称
    initialState:{     // 初始数据 对象
        num:0,
        qwe:"大哥"
    },
    reducers:{          // 重新处理数据
        ADD:(state,action)=>{       // 数据加
            console.log(action);
            // state 代表数据原
            state.num = state.num +  action.payload
        },
        Reduce:(state,action)=>{
            state.num = state.num -  action.payload
        },
    }      
})

console.log(reducerSum,123);
export const {ADD,Reduce} = reducerSum.actions;  // 暴露行为给组件调用
export default reducerSum.reducer;  // 暴露reduce纯函数给仓库store

组件使用数据

import { useStore, useSelector, useDispatch } from "react-redux"
import { Reduce } from "../redux/reducers/reduceSum"


export default function Sum() {
    const store = useStore()
    console.log(store.getState().reducerSum.num,"useStore");

    const {num,qwe} = useSelector((state)=>state.reducerSum)
    console.log(num,"num");

    const dispatch = useDispatch()

    const handlAdd = ()=>{
        // dispatch({type: 'reducerSum/ADD',payload:1})
        // ADD(123)
        // dispatch(ADD(123)) 
    }

    const handlreduc = ()=>{
        dispatch(Reduce(10))
    }
  return (
    <div>
        <p>Sum--{store.getState().reducerSum.num}</p>
        <p>{num}--{qwe}</p>
        <button onClick={handlAdd}>点击夹</button>
        <button onClick={handlreduc}>点击减</button>

    </div>
  )
}

书写redux的规范

1.纯函数不要返回修改上一次的state数据,建议复制一下数据,然后进行修改,再进行返回数据

/ dispatch({type: ‘reducerSum/ADD’,payload:1})
// ADD(123)
// dispatch(ADD(123))
}

const handlreduc = ()=>{
    dispatch(Reduce(10))
}

return (


Sum–{store.getState().reducerSum.num}


{num}–{qwe}


点击夹
点击减

</div>

)
}






## 书写redux的规范

> 1.纯函数不要返回修改上一次的state数据,建议复制一下数据,然后进行修改,再进行返回数据
>
> 2.reducer不要执行任何异步操作,仅仅修改数据,赋值就好了。负责修改state数据
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Redux是一个独立的JavaScript库,用于管理应用程序的状态。它提供了一个可预测的状态容器,可以在整个应用程序中共享。Redux通过单向数据流来管理状态,使得状态的变化变得可控和可预测。 React-ReduxRedux的官方绑定库,它提供了一些与React集成的功能,使得在React应用中使用Redux更加方便。React-Redux提供了一个Provider组件,它可以将Redux store传递给整个应用程序。它还提供了一个connect函数,它可以将Redux store中的状态映射到React组件的props中,使得React组件可以轻松地访问Redux store中的状态。 ### 回答2: Redux是一个用于JavaScript应用程序的状态容器,它提供了一个可预测且可维护的方式来管理应用程序的状态。Redux的核心概念是“单一数据源”,即将整个应用程序的状态存储在单一对象树中,并且任何组件都可以访问和修改该状态树的任意部分。 react-redux是一个与React紧密集成的Redux绑定库。它提供了一组React组件和API,使得使用ReduxReact应用程序中更加容易。 reduxreact-redux之间的关系可以理解为Redux是一种状态管理库,而react-reduxReduxReact之间的纽带。 具体来说,react-redux提供了两种主要的API:Provider和connect。 Provider是一个React组件,允许我们将应用程序的Redux存储连接到React组件树中的所有组件。在Provider组件内部,可以通过store属性传递Redux存储对象,使得所有组件都可以访问该存储。 connect是一个高阶组件,用于将React组件连接到Redux存储中的状态和操作。通过connect,我们可以在React组件中访问Redux状态,以及派发Redux操作。connect本质上是一个函数,它接收一个组件作为参数并返回一个新的连接了Redux存储的组件。 总之,reduxreact-redux之间的区别在于,redux是一个独立的状态管理库,而react-reduxReduxReact之间的桥梁,帮助React应用程序连接到Redux存储,并访问存储中的状态和操作。 ### 回答3: ReduxReact-Redux都是在React项目中使用的JavaScript库。Redux是一个JavaScript状态容器,用于管理应用程序中的所有状态。Redux允许将状态存储在一个单一的地方,以便在整个应用程序中共享该状态。React-ReduxReact的一个库,用于与Redux一起使用,以便在React组件中访问和更新Redux状态。 Redux通过store提供一个单一的状态树,包含了整个应用程序的状态。通过使用store中的action和reducer,Redux可以跟踪状态的所有更改。这可以帮助开发人员更容易地调试和管理代码。但是,使用Redux需要一定的时间和精力来管理各个状态,尤其在较大的代码库中尤其如此。 React-Redux库是Redux的一个扩展,它提供了一组工具来帮助React组件访问和更新Redux状态。通过提供Provider组件,React-Redux使得Redux存储的状态可以传递到整个应用程序中的所有组件。通过使用connect函数和mapStateToProps和mapDispatchToProps参数,React-Redux允许开发人员将Redux状态映射到React组件中。这样,开发人员就可以根据需要将Redux状态作为props传递给组件,并且可以更方便地将状态更改传递回Redux store。 总之,ReduxReact提供了一个易于管理的状态储存架构,以帮助应用程序开发人员管理和跟踪应用程序状态。React-Redux是一组工具,它使开发人员可以更方便地在React组件中使用Redux,从而帮助开发人员更快地开发应用程序。两者的区别在于Redux是包含整个应用程序状态的状态容器,而React-Redux则是提供了一组工具,以帮助开发人员更方便地在React组件中使用Redux状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值