当前位置:   article > 正文

使用redux-promise和redux-actions优化对redux的处理

redux 执行 dispath promises must be awaited, end with a call to .catch, end

1.准备工作

我们主要是学习与redux相关的处理,我们搭建的项目会省去路由的处理,我们会借助react的快速构建工具

create-react-app

这个工具在以前的博客中多次介绍,我们直接创建一个初始化项目(在任意位置),执行:

create-react-app stu-react-actions

等待完成...我们看一下提示,简单了解一下指令的使用

100110_BiL0_2352644.png

npm start 这个是必用的,就是在本地启动我们的项目;

npm run build 必用,构建打包好我们的项目

npm run eject 常用,帮助展开隐藏的文件和目录,因为有时候我们有对依赖模块修改的可能

现在我们切换到我们生成的项目,如果你是win系统:

cd stu-

按下tab键会帮助我们自动补全目录,回车进入项目目录。

启动项目:

npm start

100601_bgBN_2352644.png

2.利用react和react-redux构建项目

安装这2个依赖

npm install redux --save
npm install react-redux --save

等待完成,我们为什么要加--save的参数?

这样的安装会把依赖注入到package.json文件,如果别人也需要看你的项目,在启动之前只需要npm install就好了。

我就不一步一步的给大家介绍如何配置react和react-redux了,在以前的博客我有过介绍,我粘贴好最终代码。

index.js

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import App from './App';
  4. import registerServiceWorker from './registerServiceWorker';
  5. //redux 和react-redux(关联react和redux)
  6. import { createStore } from 'redux';
  7. import { Provider } from 'react-redux';
  8. //reducers 状态树state和逻辑操作
  9. import rootRedux from './rootRedux.js'
  10. //生成状态树对象
  11. const store = createStore(rootRedux);
  12. console.log(store);
  13. ReactDOM.render(<Provider store={store}><App /></Provider>, document.getElementById('root'));
  14. registerServiceWorker();

App.js

  1. import React, { Component } from 'react';
  2. import StuReactRedux from './page/StuReactRedux';
  3. class App extends Component {
  4. render() {
  5. return (
  6. <div className="App">
  7. <StuReactRedux></StuReactRedux>
  8. </div>
  9. );
  10. }
  11. }
  12. export default App;

rootRedux.js

  1. import { combineReducers } from 'redux';
  2. //子reducer
  3. import stuRedux from './store/stuRedux.js'
  4. //合并reducer
  5. var rootRedux = combineReducers({
  6. stuRedux
  7. })
  8. export default rootRedux

store/stuRedux.js

  1. //reducer
  2. var initstate={
  3. num:1,
  4. name:"小李子"
  5. };
  6. export default function (state = initstate, action) {
  7. switch (action.type) {
  8. case "ADD_NUM":
  9. return Object.assign({},state,{num:state.num+1});
  10. break;
  11. case "SET_NAME":
  12. return Object.assign({},state,{name:action.name});
  13. break;
  14. default:
  15. return state
  16. }
  17. }

page/Stu.js

  1. import React, { Component } from 'react';
  2. class Stu extends Component {
  3. render() {
  4. return (
  5. <div>
  6. <div>状态机num值:{this.props.stuRedux.num}</div>
  7. <button onClick={this.add.bind(this)}>状态机num值+1</button>
  8. <div>状态机name值:{this.props.stuRedux.name}</div>
  9. <div>状态机name值修改输入框:<input type="text" ref="sname" /></div>
  10. <button onClick={this.setname.bind(this)}>状态机name值修改</button>
  11. </div>
  12. );
  13. }
  14. add(){
  15. this.props.ADD_NUM();
  16. }
  17. setname(){
  18. this.props.SET_NAME(this.refs.sname.value);
  19. }
  20. componentDidMount() {
  21. console.log(this)
  22. }
  23. }
  24. export default Stu;

page/StuReactRedux.js

  1. import { connect } from 'react-redux';
  2. //=====引入组件=====
  3. import Stu from './Stu.js'
  4. //=====react-redux 封装组件=====
  5. // 哪些 Redux 全局的 state 是我们组件想要通过 props 获取的?
  6. function mapStateToProps(state) {
  7. return {
  8. stuRedux: state.stuRedux
  9. };
  10. }
  11. // 哪些 action 创建函数是我们想要通过 props 获取的?
  12. function mapDispatchToProps(dispatch) {
  13. return {
  14. ADD_NUM:function(){
  15. dispatch({type:"ADD_NUM"})
  16. },
  17. SET_NAME:function(val){
  18. dispatch({type:"SET_NAME",name:val})
  19. }
  20. };
  21. }
  22. //封装传递state和dispatch
  23. var StuReactRedux = connect(mapStateToProps,mapDispatchToProps)(Stu);
  24. export default StuReactRedux

浏览器预览,我们可以点击测试效果:

111239_uSMZ_2352644.png

3.异步操作

我们先说一个需求,是这样的,我们还是对num做修改,不过这是一个延时操作,我们会在500毫秒之后修改,我们对reducer的代码做修改,加入延时处理:

112203_IQkm_2352644.png

我们操作会报错,因为reducer内部是不允许异步操作的,

其实不管是同步或者异步,我们的目的是执行:

112403_aOrv_2352644.png

那么外层的异步处理,其实可以在包裹在dispatch方法外部。这样就避免了reducer内部有异步处理。

我们就按照这种处理逻辑修改,reducer撤回保持不变,在StuReactRedux.js中的

dispatch方法外部书写异步逻辑:

113649_9vTe_2352644.png

 

4.使用redux-promise让action支持异步

我们就开始学习使用redux-promise

安装redux-promise:

npm install redux-promise --save

首先说说action,他其实是一个约定好的类型对象,包含type字段等,一般action最简单结构:

{type:"SET_NAME",name:"小王"}

按照规范去做的话,结构会是这样:

  1. {
  2. type: "add_to_do_thunk",
  3. payload: {
  4. name:"tom"
  5. }
  6. }

会把数据放在约定好的规范字段payload中。

我们给dispatch的action可以使用这种方式传入:

155143_9EiL_2352644.png

对比以前,我们不过是把action让函数去返回,这时候我们在加入异步处理的话:
155124_cdX9_2352644.png

会提示错误,接收的action不支持异步方式,那么如何解决问题呢,我们的设想就是dispatch接收到产生action的函数后,会在中间加一个处理流程,自动等待异步完成,完成后在去执行一个的dispatch行为。

这时候就用到了中间件,比如我们学习的redux-promise就是这样的中间件,会利用promise帮助我们解决异步问题。

我们只需要在index.js加入这个配置:

155817_mvO5_2352644.png

现在dispath可以接收一个promise对象,然后等待返回后再去执行dispath。

我们再次修改StuReactRedux.js中生成action的处理:

160243_UcKC_2352644.png

Promise对象会被dispatch接收到,这时候会转交到中间件中,然后等到Promise对象返回成功或失败拿到传过来的action,dispatch会再次去执行我们action处理。

一个promise的简单写法演示:

  1. var b=new Promise(function(succ,err){
  2. setTimeout(function(){
  3. succ("test")
  4. },500)
  5. })
  6. b.then(function(data){
  7. console.log(data)//test
  8. })

 

5.使用redux-actions优化action处理

安装redux-actions

npm install redux-actions --save

redux-actions的第一大杀器就是createAction, 他会帮助我们生成规范的action,我们简单演示:

163809_6hNn_2352644.png

查看返回结果:

163828_4lFt_2352644.png

createAction函数的第一个就是type值,后面接受一个函数。

另一个就是handleActions,这个函数就是帮助优化代码,我们的reducer里面显示是通过switch case语句去处理的,使用handleActions函数我们可以优化写法。

164627_tVmE_2352644.png

就是对写法的优化,我们可以对比之前的代码

164706_Zpev_2352644.png

handleActions的第一个参数是一个对象,对象中的key就是action的type的值,第二个参数就是初始值的设置。

转载于:https://my.oschina.net/tbd/blog/1648601

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/510835
推荐阅读
相关标签
  

闽ICP备14008679号