一、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.如何得到此对象?
- 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 }));
3.状态和方法
1.getState() 得到state
2.dispath(action) 分发action,触发reducer调用.
3.subscribe 订阅(监听)注册监听,当产生新的state时,自动调用
四、案例实现
1.安装redux
javascript
1.npm install redux
//异步使用结合applyMiddleWare中间件
2.npm install redux-thunk
2.在项目下构建store目录
javascript
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}=action
switch(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 组件
javascript
import { Provider } from 'react-redux';
//在APP组件中使用
<Provider store={store}>
xxxx组件
</Provider>
2.connect 函数
javascript
import {connect} from "react-redux"
1.mapStateToProps 和mapDispathToProps都是函数
2.mapStateToProps 函数内置参数state mapDispathToProps 内置参数dispath
3.mapStateToProps和mapDispathToProps返回的都是对象
connect(mapStateToProps,mapDispathToProps)(UI组件)
React-Redux 使用步骤
react-redux 实例
javascript
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}=action
switch(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"