之前接到手的工程,都是别人搭好的,刚开始也是拿来就写业务,没怎么关注,最近接到一个交互比较多的工程,才开始考虑使用redux的必要性和使用方法,以及多交互情况下组件间的通信问题,以下按照工程目录和阮一峰的redux教程进行对比。http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html
首先需要明确的是,如果组件间通信不多,数据来源单一,那么redux不是特别有必要使用,比如查看信息的网站,以列表展示信息为主,分页、排序、查询都是服务器提供,那么用route区分下页面就可以了,有稍微复杂点的通信可以通过观察者模式来完成,维护起来也比较方便,但之前接触过的几个网站工程里95%都是用了react-redux,把工程变得比较复杂,应该是当初留下的,后面的人也懒得改动,直接拿来用,如下
src下的Redux目录,为Action、Reducer、Store各自建了一个目录,每个目录下又各自有一个index.js,目录结构是比较清晰的,然后一个一个js进去看,Action里的代码类似这样:
export const setMainData = (MainData) => ({
type: 'MAIN_DATA',
MainData
});
是视图上的操作需要有改变state的动作(Action)时,通过store.dispatch()来发出,在工程里可以找到这么一个方法mapDispatchToProps(react-rddux),看名字就知道是把dispatch映射到props上面,那么组件中就可以使用props.setMainData来发出setMainData这个Action了,没啥问题。
Reducer里的代码类似这样:
const MainData = (state = [], action = {}) => {
switch (action.type) {
case 'MAIN_DATA':
return action.MainData
default:
return state
}
};
这里有一点小问题,注意教程里说的Store 收到 Action 以后,必须给出一个新的 State,这样 View 才会发生变化。这种 State 的计算过程就叫做 Reducer。
Reducer是用来计算新的state用的,看这里的代码,只是原模原样的返回了action里的值,也就是说,这里的用法是,通过Action和Reducer来传值,当然这也是一种更新state的方式。
Reducer里的代码类似这样:
let store = createStore(
reducer
);
创建了store,没问题。但是store还有一个方法,store.subscribe(),工程里有这个函数,但是函数内部是空的,只有一个大括号,也就是说,State的变化,工程里是没有在监听的?其实不是,react-redux提供了这么一个方法,mapStateToProps,看教程的第三篇第四章,有这么一句mapStateToProps会订阅 Store,每当state更新的时候,就会自动执行,重新计算 UI 组件的参数,从而触发 UI 组件的重新渲染。
,所以在工程里可以看到很多用props(而不是state)作为参数进行渲染的组件,这样做有一点小问题,就是Action和Reducer对应的名字一般不一样,比如上文的setMainData和MainData,在接手一个工程的初期容易对这个变量是哪里来的一头雾水
最近越来越能体会“温故而知新”这句话的意思,阮一峰的这篇redux教程在刚接触react的时候就看过,觉得没啥用,没有get到重点,用了半年多,回头来看,感觉真的是写出了很多要点,但是自己如果没有一定程度的熟悉是无法体会到的
========================================================
补充:
上面说的我们小组里用的工程结构是一种,还有一种是按照每个页面或者每个功能,在页面或功能的目录下单独放置action和reducer;第三种是把action和reducer写在同一个文件里,可以参考这篇https://www.jianshu.com/p/34468f13263c