react全局状态管理优化

redux配合react-redux使用
安装

npm install redux
npm install react-redux

在index.js下引入Provider,以及store
通过react-redux 提供的provider提供器 将全局状态对象挂载到根元素的上下文上

import {Provider} from 'react-redux'
import store from './ReactRedux/store/store'
ReactDOM.render(<Provider store={store}><App /></Provider>, 
document.getElementById('root'));

actionType.js 存放状态值,一遍其他地方可以以变量的方式引用
避免项目复杂状态值较多的时候发生混乱

export const CHANGE_NAME = 'CHANGE_NAME'
export const CHANGE_AGE = 'CHANGE_AGE'

reducer.js
当全局状态值较复杂时可以新建一个js文件存放

import {CHANGE_NAME,CHANGE_AGE} from './actionType'

let state={
    name:'樱吹雪',
    age:16
}

export default (prevState=state,actions)=>{
    let newData = JSON.parse(JSON.stringify(prevState))
    /*
    1. 修改引用类型数据的时候回导致修改源数据,导致新数据和老数据对比为真
    2. 新数据老数据对比为真,页面不更新
    */
    let {type,payload} = actions
    
    switch (type) {
        case CHANGE_NAME:
            newData.name = payload
            break;
        case CHANGE_AGE:
            newData.age = payload
            break;
        default:
            break;
    }

    return newData
}

actionCreator.js不在发送action,单纯用来创造action

[CHANGE_NAME](){
        let action = {
            type:CHANGE_NAME,
            payload:'赤染樱'
        }
        return action
    },
    [CHANGE_AGE](){
        let action = {
            type:CHANGE_AGE,
            payload:500
        }
        return action
    }

组件中使用全局状态值,
通过react-redux 提供的connect 从跟组件的上下文上获取store对象,
通过高阶组件将获得到的store传给目标组件的props

import React,{Component} from 'react'
import {connect} from 'react-redux'
import ActionCreator from './store/actionCreator'
import {bindActionCreators} from 'redux'

class Son2 extends Component{
    render(){
        let {name,age,CHANGE_AGE} = this.props
        return(
            <div>
                <h3>son2</h3>
               {name}{age}
               <button onClick={CHANGE_AGE}>changeage</button>
            </div>
        )
    }
}


export default connect(state=>state,
dispatch=>bindActionCreators(ActionCreator,dispatch))(Son2)

connect的本质是一个方法返回一个高阶组件
参数1 mapStateToProps 映射全局状态值到props里
参数2 mapDispatchToProps 映射方法到props里,不写默认映射dispatch,return什么映射什么
mapStateToProps
本质也是一个函数

  1. 该函数接收全局状态值作为参数
  2. 该函数返回的数据会被映射到组件的props里
let mapStateToProps = (state)=>{
    console.log(state)
    console.log('mapStateToProps')
    return state
}

mapDisPatchToProps
本质也是一个函数

  1. 可以接dispatch 作为参数
  2. return的对象也会映射到props里
    mapDispatchToProps 如果为空 将dispath 映射到props里
    如果不为空 将return的对象映射到props里
let mapDispatchToProps = (dispatch) =>{
    //将ActionCreator的方法映射到组件的props属性上
    //当方法被调用时会自动执行一次dispatch
    return bindActionCreators(ActionCreator,dispatch)
}

在抛出时可以简写为

export default connect(state=>state,
dispatch=>bindActionCreators(ActionCreator,dispatch))(组件名)

redux+react-redux的异步问题
在单独使用时,异步操作可以统一放到ActionCreator中,但结合使用后,ActionCreator的方法返回值必须是一个对象
解决方法
applyMiddleWare+redux-thunk解决异步的中间件

store.js

import {createStore,applyMiddleware} from 'redux'
import thunk from 'redux-thunk' //解决异步的插件 加起来异步中间件
import reducer from './reducer'

export default createStore(reducer,applyMiddleware(thunk))

ActionCreator.js中存放异步

[CHANGE_NAME](){
        return (dispatch)=>{
            setTimeout(()=>{
                let action = {
                    type:CHANGE_NAME,
                    payload:'赤染樱'
                }
                dispatch(action)
            },1000)
        }
    }

题外话,setState的特性

constructor(){
    super()
    this.state = {
      num:1
    }
  }
componentDidMount(){
    console.log(this.state.num)//1
    this.setState({num:2})
    console.log(this.state.num)//1
    setTimeout(()=>{
      this.setState({num:3})
      console.log(this.state.num)//3
      this.setState({num:4})
      console.log(this.state.num)//4
    },0)
    console.log(this.state.num)//1
  }

setState 是个异步
但是如果setState放到了异步中 就会变成同步

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值