Redux和React组件的异步交互

Redux和React组件的异步交互

http://blog.csdn.net/github_26672553/article/details/77716004
前面一篇我们完成了一个简单的点赞功能。
页面点击事件处理函数中,我们是通过dispatch()方法,目的是要修改state。

        addClick(){
            //修改state
            store.dispatch({
                type:"INFO_CLICK"
            })

            this.setState({ //更新state
                infoData:store.getState()
            })
        }

但这里并不是异步的,是同步代码。dispatch之后就离开重新获取state了。

1、在实际开发中,我们肯定是多组件开发的,那么就意味着我们前面在组件里直接store是不可以的。
我们可以可以组件的属性,把store对象传递给组件。

<InfoDetail Store={store} />

2、这样我们就可以通过组件属性的方式获取需要的数据了

<h2>新闻标题:{this.props.Store.getState().title}</h2>
<span>点击量:{this.props.Store.getState().clicknum}</span>
this.props.Store.dispatch(); //

3、既然我们可以通过this.props.Store来获取存在store对象中的数据,那么我们构造函数constructor里也不需要去初始化state了;addClick()代码简化如下:

        addClick(){
            this.props.Store.dispatch({
                type:"INFO_CLICK"
            })
        }

但是问题来了:我们需要更新state啊

    // 组件生命周期函数
    // 组件挂载之前执行
    componentWillMount() {
        this.props.Store.subscribe(()=>{
            this.forceUpdate(); //强制更新渲染页面
        });
    }

调用store的subscribe()方法,在该方法中更新。

说好的 异步呢

官方给我们提供了一个中间件redux-thunk
安装:

npm install redux-thunk

基本原理:中间件拦截我们写的一个Thunk函数,执行异步处理完成后,进行dispatch我们正常的Action,从而继续同步更新state

1、动手吧

import {createStore, applyMiddleware} from "redux";
import thunk from "redux-thunk";

let store = createStore(InfoReduce,applyMiddleware(thunk));

注意其中的变化。

2、有了上面的变化(设置依赖),使用this.props.Store.dispatch()的时候就不必传入一个对象了,可以传入一个函数(Thunk函数)

this.props.Store.dispatch(setClickNum(101));

3、下面就要重点编写这个Thunk函数了

新建一个actions.js,我们把这类函数都写在这个文件里

import axios from "axios";

export let setClickNum = function (id) { //这是一个thunk函数
    return function (dispatch) {
        axios
            .get("http://localhost/newsdetail.php","id="+id)
            .then((response)=>{
                //response.data.clicknum 服务端返回的点赞数
                console.log(response.data);
                dispatch(InfoAction.setClickNum(response.data.clicknum)); //这句就是正规调用dispatch(action)
            })
    }
}

class InfoAction{
    static setClickNum(clicknum){
        return {
            type:"INFO_CLICK",
            num:clicknum
        }
    }
}

从代码可以看出:我们在setClickNum()函数里用了axios插件从服务端获取数据;成功获取到数据之后使用dispatch()调用action;在InfoAction类的方法实现了和Reducer的交互(也就是前篇文章中的InfoReduce.js),可以看到我们传递了type和num2个数据。

4、当然我们的InfoReduce.js代码也要改变了:

//测试数据
let info = {
    title:"测试标题",
    clicknum:0
};

// 把数据通过参数船体
export  default (state = info, action)=>{

    if (action.type == "INFO_CLICK"){
        // Object.assign()生成新的对象
        return Object.assign({},state,{clicknum:action.num});
    }

    return state;
}

通过action参数获取传递的数据。
这里写图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值