redux

redux是什么

  1. redux是一个专门用于做状态管理JS(不是react插件库)
  2. 它可以用在react, angular, vue等项目中, 但基本与react配合使用。
  3. 作用: 集中式管理react应用中多个组件共享的状态。

redux的三个核心概念

action作为store.dispatch()的参数,通知reducer如何修改

reducer修改数据

 action

  1. 动作的对象
  2. 包含2个属性
    1. type:标识属性, 值为字符串, 唯一, 必要属性
    2. data:数据属性, 值类型任意, 可选属性
  3. 例子:{ type: 'ADD_STUDENT',data:{name: 'tom',age:18} }

 reducer

  1. 用于初始化状态、加工状态。
  2. 加工时,根据旧的stateaction 产生新的state纯函数

 store

  1. stateactionreducer联系在一起的对象
  2. 如何得到此对象?
    1. import {createStore} from 'redux'
      1. const store = createStore(reducer)
      2. import reducer from './reducers'
  3. 此对象的功能?
    1. getState(): 得到state
      1. subscribe(listener): 注册监听, 当产生了新的state时, 自动调用
      2. dispatch(action): 分发action, 触发reducer调用, 产生新的state

redux的核心API

createstore()

作用:创建包含指定reducer的store对象

store对象

  1. 作用: redux库最核心的管理对象
  2. 它内部维护着:
    1. state
      1. reducer
  3. 核心方法:
    1. getState()
      1. dispatch(action)
      2. subscribe(listener)
  4. 具体编码:
    1. store.getState()
      1. store.dispatch({type:'INCREMENT', number})
      2. store.subscribe(render)

applyMiddleware()

作用:应用上基于redux的中间件(插件库)

combineReducers()

作用:合并多个reducer函数

import React, { Component } from 'react'
import store from '../../redux/store'

export default class index extends Component {
  componentDidMount(){
    //监测redux中状态的变化,只要变化,就调用render
    store.subscribe(()=>{
      this.setState({})
    })
  }

  //加法
  increment = ()=>{
    //通知redux + value
    const {value} = this.selectNumber
    store.dispatch({type:'increment',data:value*1})
  }

  //减法
  decrement = ()=>{
    const {value} = this.selectNumber
    store.dispatch({type:'decrement',data:value*1})
  }

  //奇数再加
  incrementOdd = ()=>{
    const {value} = this.selectNumber
    const sum = this.getState()
    if(sum % 2 !==0){
      store.dispatch({type:'increment',data:value*1})
    }
  }

  //异步加
  incrementAsync = ()=>{
    const {value} = this.selectNumber
    setTimeout(() => {
      store.dispatch({type:'increment',data:value*1})
    }, 500);
  }

  render() {
    return (
      <div>
        <h1>当前和为:{store.getState()}</h1>
        <select name="" id="" ref={c=>this.selectNumber = c}>
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
        <button onClick={this.increment}>+</button>
        <button onClick={this.decrement}>-</button>
        <button onClick={this.incrementOdd}>当前求和为奇数再加</button>
        <button onClick={this.incrementAsync}>异步加</button>
      </div>
    )
  }
}

 异步actions

redux异步编程

理解:

  1. redux默认是不能进行异步处理的,
  2. 某些时候应用中需要在redux中执行异步任务(ajax, 定时器)

使用异步中间件

npm install --save redux-thunk 

react-redux 

理解

  1. 一个react插件库
  2. 专门用来简化react应用中使用redux

react-Redux将所有组件分成两大类

  1. UI组件
      1. 只负责 UI 的呈现,不带有任何业务逻辑
      2. 通过props接收数据(一般数据和函数)
      3. 不使用任何 Redux  API
      4. 一般保存在components文件夹下
  2. 容器组件
      1. 负责管理数据和业务逻辑,不负责UI的呈现
      2. 使用 Redux  API
      3. 一般保存在containers文件夹下

相关API

1.Provider:让所有组件都可以得到state数据

2.connect:用于包装 UI 组件生成容器组件

3.mapStateToprops:将外部的数据(即state对象)转换为UI组件的标签属性

4.mapDispatchToProps:将分发action的函数转换为UI组件的标签属性

容器组件 

//引入UI组件
import CountUI from '../../components/Count'
//引入用于连接UI组件与redux
import {connect} from 'react-redux'
import {incrementAction,decrementAction,incrementAsyncAction} from '../../redux/count_action'

//函数的返回对象中的key作为传递给UI组件props的key,value就作为作为传递给UI组件props的value----状态
function mapStateToProps(state){
    return{count:state}
}

//函数返回的对象中的key作为传递给UI组件props的key,value就作为作为传递给UI组件props的value----操作状态的方法
function mapDispatchToProps(dispatch){
    return{
        plus:(value)=>{dispatch(incrementAction(value*1))},
        reduce:(value)=>{dispatch(decrementAction(value*1))},
        asyncPlus:(value,time)=>{dispatch(incrementAsyncAction(value*1,time))},
    }
}

//使用connect()()创建并暴露一个容器组件
const CountContainer = connect(mapStateToProps,mapDispatchToProps)(CountUI)

export default CountContainer

action作为store.dispatch()的参数,通知reducer如何修改

reducer修改数据

优化一: 简写mapDispatch

//引入UI组件
import CountUI from '../../components/Count'
//引入用于连接UI组件与redux
import { connect } from 'react-redux'
import { incrementAction, decrementAction, incrementAsyncAction } from '../../redux/count_action'

//函数的返回对象中的key作为传递给UI组件props的key,value就作为作为传递给UI组件props的value----状态
// function mapStateToProps(state){
//     return{count:state}
// }
// const mapStateToProps = state => ({ count: state })

//函数返回的对象中的key作为传递给UI组件props的key,value就作为作为传递给UI组件props的value----操作状态的方法
// function mapDispatchToProps(dispatch) {
//     return {
//         plus: (value) => { dispatch(incrementAction(value * 1)) },
//         reduce: (value) => { dispatch(decrementAction(value * 1)) },
//         asyncPlus: (value, time) => { dispatch(incrementAsyncAction(value * 1, time)) },
//     }
// }
// const mapDispatchToProps = dispatch => ({
//     plus: (value) => { dispatch(incrementAction(value * 1)) },
//     reduce: (value) => { dispatch(decrementAction(value * 1)) },
//     asyncPlus: (value, time) => { dispatch(incrementAsyncAction(value * 1, time)) },
// })

//使用connect()()创建并暴露一个容器组件
const CountContainer = connect(
    state => ({ count: state }),
    // dispatch => ({
    //     plus: (value) => { dispatch(incrementAction(value * 1)) },
    //     reduce: (value) => { dispatch(decrementAction(value * 1)) },
    //     asyncPlus: (value, time) => { dispatch(incrementAsyncAction(value * 1, time)) },
    // })
    {
        plus:incrementAction,
        reduce:decrementAction,
        asyncPlus:incrementAsyncAction,
    }
)(CountUI)

export default CountContainer

优化二: Provider组件的使用

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom'
import store from './redux/store'
import {Provider} from 'react-redux'

const root = ReactDOM.createRoot(document.getElementById('root'));

// store.subscribe(()=>{
//   root.render(
//     <React.StrictMode>
//       <BrowserRouter>
//         <App />
//       </BrowserRouter>
//     </React.StrictMode>
//   );
// })

//React.StrictMode 监测代码是否合理
//渲染app到页面
root.render(
  <React.StrictMode>
    <BrowserRouter>
      <Provider store={store}>
      <App />
      </Provider>
    </BrowserRouter>
  </React.StrictMode>
);


reportWebVitals();

优化三: 整合UI组件和容器组件

import React, { Component } from 'react'
//引入用于连接UI组件与redux
import { connect } from 'react-redux'
import { incrementAction, decrementAction, incrementAsyncAction } from '../../redux/count_action'

class Count extends Component {
  // componentDidMount(){
  //   //监测redux中状态的变化,只要变化,就调用render
  //   store.subscribe(()=>{
  //     this.setState({})
  //   })
  // }

  componentDidMount(){
    console.log('???',this.props)
  }

  //加法
  increment = ()=>{
    //通知redux + value
    const {value} = this.selectNumber
    this.props.plus(value*1)
  }

  //减法
  decrement = ()=>{
    const {value} = this.selectNumber
    this.props.reduce(value*1)
  }

  //奇数再加
  incrementOdd = ()=>{
    const {value} = this.selectNumber
    const sum = this.props.count
    if(sum % 2 !== 0){
      this.props.plus(value*1)
    }
  }

  //异步加
  incrementAsync = ()=>{
    const {value} = this.selectNumber
    //store.dispatch(incrementAsyncAction(value*1,500))
    this.props.asyncPlus(value*1,500)
  }

  render() {
    return (
      <div>
        <h1>当前和为:{this.props.count}</h1>
        <select name="" id="" ref={c=>this.selectNumber = c}>
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
        <button onClick={this.increment}>+</button>
        <button onClick={this.decrement}>-</button>
        <button onClick={this.incrementOdd}>当前求和为奇数再加</button>
        <button onClick={this.incrementAsync}>异步加</button>
      </div>
    )
  }
}

//使用connect()()创建并暴露一个容器组件
export default connect(
    state => ({ count: state }),
    {
        plus:incrementAction,
        reduce:decrementAction,
        asyncPlus:incrementAsyncAction,
    }
)(Count)

 

import { applyMiddleware, legacy_createStore as createStore, combineReducers} from 'redux'
import countReducer from './reducers/count_reducer'
import personReducer from './reducers/person'
import thunk from 'redux-thunk'
import {composeWithDevTools} from 'redux-devtools-extension'

//传入的参数就是redux所维护的状态对象
const allReducer = combineReducers({
    persons:personReducer,
    sum:countReducer,
})

export default createStore(allReducer,composeWithDevTools(applyMiddleware(thunk)))

 

import { applyMiddleware, legacy_createStore as createStore, combineReducers} from 'redux'
import countReducer from './reducers/count_reducer'
import personReducer from './reducers/person'
import thunk from 'redux-thunk'
import {composeWithDevTools} from 'redux-devtools-extension'

//传入的参数就是redux所维护的状态对象
const allReducer = combineReducers({
    persons:personReducer,
    sum:countReducer,
})

export default createStore(allReducer,composeWithDevTools(applyMiddleware(thunk)))

 

 多个reducer会逐个匹配,default 的 返回值 要返回当前值。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值