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