一、Redux是什么?
1.Redux是一个专门用于状态管理的js库
2.它可以用在React、Angular、Vue的项目中,但基本与React配合使用。
3.作用:集中式管理React应用中多个组件共享的状态。
二、Redux 工作流程
三、Redux的三个核心概念
1.action
动作对象,包含2个属性
type: 标识属性,值为字符串,唯一,必要属性
data: 数据属性,值类型任意,可选类型
例子:{ type: ‘increment’, data: 1}
2.reducer
1.用于初始化状态、加工状态
2.加工时,根据旧的state和action,产生新的state的纯函数
3.reducer是一个函数 countReducer(initState=0,action)
3.store
1.将state、action、reducer联系在一起的对象
2.如何得到此对象?
1. import { createStore } from ‘redux’
注意:createSotre 在新版本中提示已过期可以换成
import { legacy_createStore as createStore } from “redux”;
2.import count from ‘./reducer’
3.const store = createStore(reducer)单个reducer
4.createStore(combineReducers({ count: countReducer, person: personReducer }));
5.
3.状态和方法
1.getState() 得到state
2.dispath(action) 分发action,触发reducer调用.
3.subscribe 订阅(监听)注册监听,当产生新的state时,自动调用
四、案例实现
1.安装redux
1.npm install redux
//异步使用结合applyMiddleWare中间件
2.npm install redux-thunk
2.在项目下构建store目录
1.构建index.js 主文件,代码如下:
import {
legacy_createStore as createStore,
combineReducers,
applyMiddleware
} from "redux"
import countReducer from "./reducers/countReducer"
//异步使用,注意:异步返回的action是一个函数
//非异步返回的是普通对象{action:xxxx,data:xxxx},且使用中间件applyMiddleWare
//多个reducer使用combieReducers结合起来使用{key:value}模式
//reducer 是一个函数
import {thunk} from "redux-thunk"
export default createStore(combineReducers( {count:countReducer}),applyMiddleware(thunk))
2.分别构建reducers目录、actions目录、及constant.js 常量化文件的模块化思想
1.actions 目录下构建 countAction.js 文件,代码如下:
import {increment,decrement} from "../constant"
export function incrementAction(data)
{return {type:increment,data}
}export function decrementAction(data)
{return {type:decrement,data}
}
//如果是异步返回的是函数
export function asyncAddValue(data,interval) {//默认会回传dispatch函数return (dispatch)=>{setTimeout(()=>{dispatch(incrementAction(data))},interval)}
}
2.在reducers目录下构建countReducer.js文件
import { act } from "react"
import {increment,decrement} from "../constant"
export default function countReducer(initState=0,action)
{const {type,data}=actionswitch(type){case increment:return data+initState;case decrement:return initState-data;default:return initState;}
}
3.在constant.js 常量文件中配置常量
export const increment="INCREMENT"
export const decrement="DECREMENT"
export const addPerson="ADDPERSON"3.项目下构建Components文件夹,里面构建count文件夹,count文件夹中构建index.js文件
import React,{Component} from 'react'
import store from "../../store/index"
import {incrementAction,decrementAction,asyncAddValue} from "../../store/actions/countAction"
export default class Count extends Component
{//构建状态state={selectValue:1}//通过受控组件模式获取下拉框的值selectGetValue=(e)=>{this.setState({selectValue:e.target.value})}//添加值addValue=()=>{//通过dispatch 分发分派动作 {action:xxxx,data:xxxx}store.dispatch(incrementAction(this.state.selectValue*1))}//减去值substractValue=()=>{store.dispatch(decrementAction(this.state.selectValue*1))}oddAddValue=()=>{//获取store中的状态必须用 getState() 获取状态const {count}=store.getState()if(count%2!==0)store.dispatch(incrementAction(this.state.selectValue*1))}asyncAddValue=()=>{store.dispatch(asyncAddValue(this.state.selectValue*1,500))}//生命周期函数:组件完全挂载完成componentDidMount(){//redux状态更改在ui中呈现,必须的订阅 subscribe 结合 setState 状态改变store.subscribe(()=>{this.setState({})})}render(){return <div><div>{store.getState().count}</div><div>{this.state.selectValue}</div><div><select onChange={this.selectGetValue}><option value="1">1</option><option value="2">2</option><option value="3">3</option><option value="4">4</option></select><button onClick={this.addValue}>增加</button><button onClick={this.substractValue}>减少</button><button onClick={this.oddAddValue}>奇数增加</button><button onClick={this.asyncAddValue}>异步增加</button></div></div>}
}
React-Redux
Redux和React-Redux的区别
①:redux和组件进行对接的时候是直接在组件中进行创建。react-redux是运用Provider将组件和store对接,使在Provider里的所有组件都能共享store里的数据,还要使用connect将组件和react连接。
②:获取state的方式不一样
redux获取state是直接通过store.getState()。
react-redux获取state是通过mapStateToProps函数,只要state数据变化就能获取最新数据
③触发action的方式不一样。
redux是使用dispatch直接触发,来操作store的数据。
react-redux是使用mapDispathToProps函数然后在调用dispatch进行触发
React-Redux的工作原理
React-redux是一个redux的官方绑定react库,也是有三要素store,reducer,action 但是获取store中的数据与事件方法不一样,首先使用Provider标签将组件包裹起来,使store与组件对接,并且向store分发actions以更新数据,在组件中通过connect函数将组件与react对接,其中有两个参数一个是mapStatetoprops负责接收store中的数据,另一个是mapDispatchtoProps负责接收传递过来的的actions
React-Redux和Redux及UI之间的关系
Rect-Redux的常用功能
1.Provider 组件
import { Provider } from 'react-redux';
//在APP组件中使用
<Provider store={store}>xxxx组件
</Provider>
2.connect 函数
import {connect} from "react-redux"
1.mapStateToProps 和mapDispathToProps都是函数
2.mapStateToProps 函数内置参数state mapDispathToProps 内置参数dispath
3.mapStateToProps和mapDispathToProps返回的都是对象
connect(mapStateToProps,mapDispathToProps)(UI组件)
React-Redux 使用步骤
react-redux 实例
1.安装 react-redux
npm install react-redux
2.index.js 使用Provider 组件注册 store
import React from 'react'
import ReactDOM from "react-dom/client";
import App from "./App"
import {Provider} from "react-redux"
import store from "./store/index"
const root=ReactDOM.createRoot(document.getElementById("root"))
root.render(<React.StrictMode><Provider store={store}><App></App></Provider></React.StrictMode>
)
3.构建容器组件用connect函数连接UI组件
import React,{Component, createRef} from "react"
import {connect} from "react-redux"
import {addPersonFun} from "../../store/actions/personAction"
import {nanoid} from "nanoid"
class Person extends Component
{userRef=createRef()//添加人员addPerson=()=>{const obj={userName:this.userRef.current.value,id:nanoid(),age:19}this.props.addPerson(obj)}render(){return <div><div><label htmlFor="userName">用户名:</label><input type="text" id="userName" ref={this.userRef}/><button onClick={this.addPerson}>添加人员</button></div><ul>{this.props.persons.map((item,index)=>{return <li key={item.id}>{item.userName}-{item.age}- {item.id}</li>})}</ul>
</div>}
}
function mapStateToProps(state) {return {persons:state.person}
}
function mapDispathToProps(dispath) {return {addPerson:(data)=>{dispath(addPersonFun(data))}}
}
//connect 连接UI组件和mapStateToProps以及mapDispathToProps
export default connect(mapStateToProps,mapDispathToProps)(Person)4.store 的redux主文件index.js,combineReuders 合并personReducer.js
import {legacy_createStore as createStore,combineReducers,applyMiddleware} from "redux"
import countReducer from "./reducers/countReducer"
import personReducer from "./reducers/personReducer"
import {thunk} from "redux-thunk"
export default createStore(combineReducers(
{count:countReducer,person:personReducer
}
),applyMiddleware(thunk))
5.personReducer.js 内容代码如下:
import {addPerson} from "../constant"
export default function personReducer(initState=[],action)
{const {type,data}=actionswitch(type){case addPerson:return [data,...initState]default:return initState}
}
6.personAction.js 代码如下:
import {addPerson} from "../constant"
export function addPersonFun(data) {return {type:addPerson,data}
}
7.constant.js 代码如下:
export const increment="INCREMENT"
export const decrement="DECREMENT"
export const addPerson="ADDPERSON"