Redux异步方案实现

一、不借用第三方库实现Redux异步

场景建立:先来个很常见的场景,在Http请求之前我们一般会用loading组件来表示数据正在请求,等Http请求结束就关闭loading。下图所示的是Http请求的3种状态:

在这里插入图片描述

上述场景如果不使用redux状态管理器,我们会使用react的state或hooks特性来实现;如果使用redux该怎么实现呢?

redux是通过dispatch()方法去触发reducer机制去改变state的。一般情况下,正常的HTTP请需要执行dispatch()三次。如下所示:

dispatch({type:"LOAD_ACTION_START"}); //开始请求
dispatch({type:"LOAD_ACTION_SUCCESS"}); //请求成功
dispatch({type:"LOAD_ACTION_ERROR"}); //请求失败

大概的实现流程如下代码所示:

class DemoView extends Component {
  getHttpData=()=>{ //获取HTTP请求——核心代码
    Store.dispatch(LOAD_ACTION_FUNS(LOAD_ACTION_START));
    setTimeout(()=>{ //模拟http请求
      const res={ //模拟服务器返回的数据
        flag:"success",
        msg:"",
        datas:[
          {
            title:"请求成功"
          },{
            title:"请求成功"
          },{
            title:"请求成功"
          }
        ]
      }
      if(res["flag"] == "success"){ //请求成功
        Store.dispatch(LOAD_ACTION_FUNS(LOAD_ACTION_SUCCESS,{datas:res['datas']}));
      }else{ //请求失败
        Store.dispatch(LOAD_ACTION_FUNS(LOAD_ACTION_SUCCESS,{msg:res['msg']}));
      }
    },3000);
  }

  render(){
    //忽略
    return null;
  }
}

从上面代码可知,如果单纯使用redux也可以实现异步redux。不过不建议这么做。react属于UI以构建 UI 为主的的库。尽量将数据逻辑与View分离,简化View层面的逻辑。可以借助第三库实现View层或数据层的分离,降低耦合度。有利于代码梳理;

二、借用第三方库实现Redux异步
  1. react-redux:属于将react项目与redux进行绑定关联的第三方库;
  2. redux-chunk:可以将dispatch()的参数定义为函数的中间件;

Redux中间件:中间件一般用来处理action对象。而action对象通过dispatch()方法派发给reducer处理。在进入reducer之前那阶段称之为中间件管道。也就是通过在中间管道之间执行一系列中间件功能以达到增强action功能,最终进入reducer处理;

react-redux主要提供Provider组件和connect()方法;如果没有用Provider组件包裹根组件,connect()方法也无效

  1. Provider组件:使你的react应用能够访问到redux;
  2. connect()方法:将你的react组件和redux关联起来;
//Provider组件的用法
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
)
//connect()方法的用法
import React, { Component } from 'react';
import {View,Text,Button,FlatList} from "react-native";

import {connect} from "react-redux";
//这里封装了redux异步写法
import {MeSettingAction} from "../../redux/mesetting";

class MeSettingView extends Component{
  componentDidMount(){
    this.props.initUserInfo();
  }
  render(){
    //使用connect(mapStateToProps)中userInfo
    const userInfo=this.props.userInfo;
    return (
      <View style={styles.mAddBox}></View>
    );
  }
}

export default connect((state)=>{ //mapStateToProps
  return {
    userInfo:state['userInfo']
  }
},(dispatch)=>{ //mapDispatchToProps
  return {
    initUserInfo:()=>dispatch(MeSettingAction())
  }
})(MeSettingView);
import {HttpAjax,} from "../utils";

const initState={
  type:0, //是否请求成功的状态->0:未开始;1:正在请求;2:请求成功;3:请求失败
  msg:"", //请求后的描述
  datas:[] //请求返回的数据
};

export const MeSettingReducer=(state=initState,action)=>{
  switch(action['type']){
    case "MESETTING_START":
        return {...state,type:1};
    case "MESETTING_SUCCESS":
        return {...state,type:2,datas:action['payload']};
    case "MESETTING_ERROR":
        return {...state,type:3,datas:action['payload']};
    default:
      return state;
  }
}

export const MeSettingAction=()=>{
  return async (dispatch)=>{
    //开始请求
    dispatch({type:"MESETTING_START"});
    const url="";
    const sendData={};
    return new Promise((resolve,reject)=>{
      HttpAjax(url,sendData,'get').then((res)=>{
        const result=JSON.parse(res);
        if(result['flag'] == "success"){
          //请求成功
          dispatch({type:"MESETTING_SUCCESS",payload:result['datas']});
        }else{
           //请求失败
          dispatch({type:"MESETTING_ERROR",payload:result['msg']});
        }
        resolve(result);
      }).catch((err)=>{
        //请求失败
        dispatch({type:"MESETTING_ERROR",payload:"请求失败"});
        reject(err);
      });
    })
  }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值