redux 使用流程

1. 安装依赖 两个包

 npm i redux react-redux --dev           //或者(yarn add)

2. 在 src/store/reducers/index.js 管理员 负责数据操作记录

3. 在 src/store/index.js 仓库

4. 在入口的js文件 index.js 来引入 store 入口文件引入后组件就可以使用

1. 需要将 store和 App.js 产生一些联系 (使用redux的连接器,入口文件和仓库管理员产生链接)组件

5. 在App.js中 使用store中的数据

管理员文件(包含派发流程)

//在管理员的index内定义默认的数据
const defaultState = {
  num: 1000
}
//暴露数据出去,
// state的数据,就可以在外面使用了
// 通过action方法处理改变state内的数据
export default (state = defaultState, action) => {
    //对所有派发数据修改修改事件,都进行判断
  if (action.type === 'change') {
    //说明是数字修改的派发事件
    let newState = JSON.parse(JSON.stringify(state)) //必须要深克隆,否则无法触发视图更新
    newState.num += action.value //改变管理员的值
    return newState //需要返回值
  }
  return state
}

 

在仓库内链接管理员,并且暴露出去

//引入管理员暴露的数据模块
import reducers from "./reducers/index"

//引入redux内的仓库生成器方法
import { createStore } from 'redux'

//将管理员和仓库一起导出去(生成仓库)
export default createStore(reducers)

 

入口文件挂载仓库

// 引入仓库文件
import store from './store/index'

// 引入redux和react的连接器的方法
import { Provider } from 'react-redux'

//将Provider包裹住App ,并且在标签上传入store数据
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

 

 

使用方式(组件)

//引入连接器(将仓库和当前组件链接起来,
import { connect } from 'react-redux'

//state就是在管理员那里声明过的state了,而state= defaultState 所以,拿到数据后,直接给了num
const mapStateToProps = state => {
  return {
    num: state.num
  }
}
在组件内触发该事件<button onClick={this.props.changeNum}>+</button>
//派发修改仓库数据的方法
//数据修改时,进行派发的方法
const mapDispatch = dispatch => {
  return {
    changeNum: () => {//组件需要触发的事件,一旦触发就立即派发了change
      // 创建action,该名称并不是写死的,只是派发了一个修改的独享过去
      const action = {
        type: 'change', //派发修改操作的名称,在仓库那边可以通过此名称进行验证的
        value: 1 //需要更改的值每次点击的时候,更改多少数据
      }
      dispatch(action) //开始派发这一事件
    }
  }
}
//将当前组件和仓库链接起来,store的数据就可以在组件内使用
export default connect(mapStateToProps, mapDispatch)(CarouselImg)
//第一个放数据,第二个放方法的
connect(mapStateToProps, null)(CarouselImg)
 使用方式
 {this.props.num} //即可得到当前仓库内的数据

 

Store仓库负责连接管理和组件,所有的数据,都在管理员文件内

在组件内派发事件this.props.事件名(changeNum)

获取仓库数据this.props.num

 

注意

如果当前组件内,还有其他的组件,要用{...this.props}传给子组件,否则,其他的子组件是没有仓库内的数据的,

如果按钮组件被封装了,但是连接器只连接到了当前组件,还要给按钮组件传入props

class AddButton extends Component {
  render() {
    console.log(this.props)//空
    return <button onClick={this.props.changeNum}>+</button>
  }
}


父组件
<button onClick={this.props.jian}>-</button>
        {this.props.num}
 <AddButton {...this.props}></AddButton> //rudex的数据,在当前注册时,就只给了父组件,子组件没有。如果需要用props内的
 方法和数据,需要手动的添加到子组件上

 

常量优化

避免因为字符写错出问题,如果用常量,则写错后提示报错

1 在reducers同层级新建actionType文件夹新建index.js

2 导入常量

export const CHANGE_NUM = 'CHANGE_NUM'

 

管理员文件redux内判断也要更改

import { CHANGE_NUM } from '../actionsType/index' //引入定义的常量
 if (action.type === CHANGE_NUM) {
    //说明是数字修改的派发事件
    let newState = JSON.parse(JSON.stringify(state)) //必须要深克隆,否则无法触发视图更新
    newState.num += action.value //改变管理员的值
    return newState //需要返回值
  }

 

4派发方法的组件内引入常量

import { CHANGE_NUM } from '../store/actionsType/index'
changeNum: () => {
      //组件需要触发的事件,一旦触发就立即派发了change
      // 创建action
      const action2 = {
        type: CHANGE_NUM, //派发修改操作的名称,在仓库那边可以通过此名称进行验证的
        value: 1 //需要更改的值每次点击的时候,更改多少数据
      }
      dispatch(action2)
    },

 

 

派发事件的单独封装

 

reducers文件夹同层级新建文件夹actionCreator 下index

保存所有的派发事件

import { JIAN_NUM } from '../actionsType/index' //引入外部命名的常量

//暴露出派发的事件 可通过调用numJian 传入num 动态修改减少的数量
export const numJian = (num) => {
  return {
    type: JIAN_NUM,
    value: num
  }
}


在组件内导入actionCreator内的index
import { numJian } from '../store/actionCreator/index' //派发的方法
//数据修改时,进行派发的方法
const mapDispatch = dispatch => {
  return {
    jian: () => {
        //实际上抽离代码,放在另外一个地方了
      dispatch(numJian(1))
    }
  }
}

 

 

拆分合并多个reduers

store/reducers/1.js
store/reducers/2.js
两个代码一样


引入要合并的管理员文件
import data1 from "./1";
import data2 from "./2";

// 2 引入 合并工具
import { combineReducers } from "redux";

// 3 合并并导出  
export default combineReducers({data1,data2});

//取数据的时候,会有影响
const mapStateToProps = (state) => {
  console.log(state);
  return {
    // 修改成 1 多加了一层
    num: state.data1.num
  }
}

 

 

异步修改action

store/actionTypes/index.js 新增异步常量名

export const START_NUM = 'START_NUM'

 下包

npm i redux-thunk axios --dev

 

在仓库内,重新载入下好的异步模块(修改)

//引入redux内的连接器  在加入另外一个连接器
import { createStore,applyMiddleware } from 'redux'

//引入异步工具
import reduxThunk from 'redux-thunk'

//将管理员和仓库一起导出去(修改)
export default createStore(reducers, applyMiddleware(reduxThunk))

 

store/actionCreator/index内新增异步请求

import { START_NUM } from '../actionsType/index.js' //引入定义好的常量名
//初始化异步请求
export const startNum = () => {
  return dispatch => {
    setTimeout(() => {
      const action = {
        type: START_NUM,
        value: 999999
      }
      dispatch(action) 
    }, 2000)
  }
}

 

在组件内引入并且调用

import {startNum } from '../store/actionCreator/index' //派发的方法
componentDidMount() {
    生命周期,在页面初始化的时候调用
    this.props.startcNum() //触发redux内异步方法
  }
const mapDispatch = dispatch => {
    //异步数据请求
    startcNum:()=>{
      dispatch(startNum()) //异步方法的定义
    }
}
export default connect(mapStateToProps, mapDispatch)(CarouselImg)

 

redux管理员处理异步回来的数据

import {START_NUM } from '../actionsType/index'
//在管理员的index内定义默认的数据
const defaultState = {
  num: 1000
}
//暴露数据出去,
// state的数据,就可以在外面使用了
// 通过action方法处理改变state内的数据
export default (state = defaultState, action) => {
  //对所有派发数据修改修改事件,都进行判断
  let newState = JSON.parse(JSON.stringify(state)) //必须要深克隆,否则无法触发视图更新
  //异步更新
  console.log(action)
  if (action.type === START_NUM) {
    newState.num = action.value
    return newState //需要返回值
  }
  return state
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值