Redux和React组件的异步交互

xiaoxiao2021-02-28  75

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参数获取传递的数据。

转载请注明原文地址: https://www.6miu.com/read-42689.html

最新回复(0)