redux基础使用(redux-thunk,react-redux拆分)

一:redux介绍以及使用

redux简介

redux是react中进行state状态管理的JS库(并不是react插件)
一般是管理多个组件中共享数据状态

1 redux组成部分

store:用来存储数据
reducer:真正的来管理数据
actionCreators:创建action,交由reducer处理
view: 用来使用数据,在这里,一般用react组件来充当

2 需要使用redux的项目

用户的使用方式复杂
不同身份的用户有不同的使用方式(比如普通用户和管理员)
多个用户之间可以协作
与服务器大量交互,或者使用了WebSocket
View要从多个来源获取数据

3 从组件层面考虑,什么样子的需要redux

某个组件的状态,需要共享
某个状态需要在任何地方都可以拿到
一个组件需要改变全局状态
一个组件需要改变另一个组件的状态

4 redux执行流程

1.创建store
从redux工具中取出createStore去生成一个store
2.创建一个reducer
然后将其传入到createStore中辅助store的创建
reducer是一个纯函数,接收当前状态和action,返回一个状态,返回什么store的状态就是什么,需要注意的是,不能直接操作当前状态,而是需要返回一个新的状态,想要给store创建默认状态其实就是给reducer一个参数创建默认值
3.组件通过调用store.getState方法来使用store中的数据
4.组件产生用户操作
调用actionCreator的方法创建一个action,利用store.dispatch方法传reducer
5.reducer对action上的标示性信息做出判断后对新状态进行处理,然后返回新状态,这个时候store的数据就会发生改变,reducer返回什么状态,store.getState就可以获取什么状态
6.我们可以在组件中,利用store.subscribe(callback)方法去订阅数据的变化
也就是可以传入一个函数,当数据变化的时候,传入的函数会执行,在这个函数中让组件去获取最新的状态
请添加图片描述

二:redux应用

1 安装redux
npm i redux --save
2 新增Count 组件

绑定事件调用store.dispatch方法(参数为action)传递reducer

import store from '../../redux/store'
export default class Count extends Component {
 	// 加
    add = ()=>{
       const { value } =  this.refs.selectVal;
       store.dispatch({type:"add",data:value*1})
    }
    // 减
    sub = ()=>{
        const { value } =  this.refs.selectVal;
            store.dispatch({type:"sub",data:value*1})
   }
   // 异步减
   subAsync = ()=>{
        const { value } =  this.refs.selectVal;
        setTimeout(()=>{
            store.dispatch({type:'add',data:value*1})
        },500)
   }
   render() {
        return (
            <div>
                <p>计算出的数值为: {store.getState()}</p>
                <select ref="selectVal" style={{width:"50px"}}>
                   <option value="1">1</option>
                   <option value="2">2</option>
                   <option value="3">3</option>
                </select>
                <button onClick={this.add}>+</button>
                <button onClick={this.sub}>-</button>
                <button onClick={this.subAsync}>-</button>
            </div>
        )
    }
}
3 src下新建store文件,index.js
 1 引入redux中的createStore函数,创建一个store
 2 createStore调用时要传入一个为其服务的reducer
 3 暴露store对象
import {createStore} from 'redux'
import reducer from './reducers'
export default createStore(reducer)
4 store文件下新建reducers.js
1.reducer的本质是一个函数,接收:preState,action,返回加工后的状态
2.reducer有两个作用:初始化状态,加工状态
3.reducer被第一次调用时,是store自动触发的,
         传递的preState是undefined,
         传递的action是:{type:'@@REDUX/INIT_a.2.b.4}
const initialization = 0
function reducers(preState=initialization,action){
    const {type,data} = action
    if(type ==="add"){
      return  data + preState
    }else if(type ==="sub"){
        return  preState - data
    }else{
        return 0
    }
}
export default reducers
5 在根路径index.js调用store.subscribe方法驱动页面刷新
ReactDOM.render(<App/>,document.getElementById('root'))
store.subscribe(() => {
  ReactDOM.render(<App />, document.getElementById("root"));
});

三:异步拆分actions

将异步任务放在store中执行异步actions

1 store下index.js文件添加代码

安装redux-thunk中间件解决异步问题

yarn add redux-thunk
import {createStore,applyMiddleware} from 'redux'
//引入redux-thunk,用于支持异步action
import thunk from 'redux-thunk'
//暴露store
export default createStore(reducer,applyMiddleware(thunk))
2 store文件下新建actions.js
1.store文件下新建constant.js放置容易写错的type值
2.同步action方法拆分
3.异步action接收两个参数,需要返回一个函数,接收参数dispatch
// 该文件专门为Count组件生成action对象
import {INCREMENT,DECREMENT} from './constant'
//同步action,就是指action的值为Object类型的一般对象
export const add = data => ({type:INCREMENT,data})
export const sub = data => ({type:DECREMENT,data})
// 异步action,就是指action的值为函数,
// 异步action中一般都会调用同步action,异步action不是必须要用的。
export const addAsync = (data,time) => {
    return (dispatch)=>{
        setTimeout(()=>{
            dispatch(add(data))
        },time)
    }
}
3 constant.js
一种规范,防止变量重复造成误解(引入错误)
export const INCREMENT = 'add'
export const DECREMENT = 'sub'
4 组件中调用
add = ()=>{
    const { value } =  this.refs.selectVal;
    store.dispatch(add(value*1))
}
addAsync = ()=>{
    const { value } =  this.refs.selectVal;
    store.dispatch(addAsync(value*1,500))
}

四:react-redux的使用

1 react-redux概念及方法
1.UI组件:不能使用任何redux的api,只负责页面的呈现、交互等。
2.容器组件:负责和redux通信,将结果交给UI组件

新建容器组件用于和redux通信
调用connect(mapStateToProps,mapDispatchToProps)(UI组件)方法
接收两个参数都为函数
1 处理传递状态
mapStateToProps:映射状态,返回值是一个对象
2 处理传递状态的方法
mapDispatchToProps:映射操作状态的方法,返回值是一个对象,容器组件中的store是靠props传进去的,而不是在容器组件中直接引mapDispatchToProps,也可以是一个对象

2 react-redux和redux区别

1 redux和组件进行对接的时候是直接在组件中进行创建。
react-redux是运用,一个组件和store对接,使在组件里的所有组件都能共享store里的数据,还要使用connect将组件和react连接。
2 获取state的方式不一样
redux获取state是直接通过store.getState()。
react-redux获取state是通过mapStateToProps函数,只要state数据变化就能获取最新数据
3 触发action的方式不一样。
redux是使用dispatch直接触发,来操作store的数据。
react-redux是使用mapDispathToProps函数然后在调用dispatch进行触发

3 react-redux具体使用
/引入Count的UI组件
import count from '../../pages/count'
//引入action
import {add,sub,addAsync} from '../../store/actions'
//引入connect用于连接UI组件与redux
import {connect} from 'react-redux'
/* 
    1.mapStateToProps函数返回的是一个对象;
    2.返回的对象中的key就作为传递给UI组件props的key,value就作为传递给UI组件props的value
   3.mapStateToProps用于传递状态
   4.接收一个参数state
*/
function mapStateToProps (state){
    return {count:state}
}

/* 
    1.mapDispatchToProps函数返回的是一个对象;
    2.返回的对象中的key就作为传递给UI组件props的key,value就作为传递给UI组件props的value
    3.mapDispatchToProps用于传递操作状态的方法
    4.接收一个参数dispatch
*/
function mapDispatchToProps (dispatch){
    return {
        add:number => dispatch(add(number)),
        sub:number => dispatch(sub(number)),
        addAsync:(number,time) => dispatch(addAsync(number,time)),
    }
}
export default connect(mapStateToProps,mapDispatchToProps)(count)

修改count组件为ui组件拆除redux功能
通过this.props可以拿到视图组件传递过来的数据方法

import React, { Component } from 'react'
export default class Count extends Component {
    // 通过this.props可以拿到
    add = ()=>{
       const { value } =  this.refs.selectVal;
       this.props.add(value*1)
    }
    sub = ()=>{
        const { value } =  this.refs.selectVal;
        this.props.sub(value*1)
    }
    addAsync = ()=>{
        const { value } =  this.refs.selectVal;
        this.props.addAsync(value*1,1000)
    }
}

在App.js文件,引入store,改为显示ui组件

import Ui from "./components/ui"
import store from "./store/index"
function App() {
  return (
    <div >
        <Ui store={store}/>
    </div>
  );
}
export default  App;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值