查看原文
其他

手把手教你用react

2016-08-10 Doerme 前端圈
最近有机会接触到Hybrid项目,终于有机会浅尝一下eact。
先介绍一下如何使用工作流:


Yeoman上已经有很多出色的工作流,不妨先拿来一用,以后有空再自己折腾工作流吧。


npm install -g yonpm install -g generator-react-webpack
然后clone一下本人稍作修改的开发代码(增加react-router、Redux的引用,以及工作流上增加了postcss的输出)git clone https://github.com/doerme/react-router-redux.git
接下来进入目录安装package.json的依赖包cd react-router-reduxnpm i
好了,到这一步你可以看看效果了。npm run start

你可以点击 Home About Repos 切换路由,点击Increase,Decrease,Write 改变数值的显示。


接下来看一下代码:

cfg是webpack的配置文件夹;dist是打包生成的目标文件夹;test是测试文件夹;


重点需要理清的是src开发目录,components是项目组件目录,actions是存放事务操作数据的行为抽象方法文件,reducers是存放用来触发dispatch修改store的文件(具体见下文);

src/index.js是入口文件,先来看看import的内容:


首先引入的是react,嗯!别问我为什么。


然后是引入react-domrender,react-dom是react的一部分,其主要是返回一些react操作dom的交互API,我们要用的是render,其作用是在dom中渲染react的组件。
然后是引入Redux,我们需要用到的是createStorecombineReducers,redux是一个数据状态管理类,我们就是要用redux来管理react的状态数据。其中createStore这个API是用来创建一个存储库,相对与状态管理来说,createStore是用来创建一个完整项目状态管理树,且一个项目只有一个状态管理树。


在开发过程之中,随着应用的复杂,状态也越来越多,所以我们会也需要划分多个reducer函数来处理这些状态,combineReducers作用就是要把这些拆分开的reducer函数合拼成一个reducer,然后传给createStore;


然后是引入react-reduxProvider<Provider store>是一个能使其下所以子组件都能使用connect方法与Redux store交互的组件API;
之后是引入react-router,我们会用到Router, Route, hashHistory, IndexRoute。Router是react-router的关键组件,其作用是让页面UI与路由同步;Route是属于配置组件,用来一对一映射路由规则与相对应的组件;IndexRoute也是一个配置组件,其是用来指定根目录路径对应显示的组件;hashHistory作用是跟踪URL hash值的状态变化;


最后引入的是react-router-redux,从名字就可以看出react-router-redux是一个让redux与router能一起搭配使用的react组件库。其主要作用是把router发生变化的状态同步到redux的store之中;在这个项目中我们使用了syncHistoryWithStorerouterReducer

routerReducer是一个reducer方法,其作用是当url发生变化时候更新store的location;


syncHistoryWithStore作用是把react-router的url变化历史hashHistory更新到redux的store之中,这样可以使url状态变化与store更新同步。


接下来,我们来看一下点击页面的链接(Home About Repos)时候,视图发生变化的原理:


仍然是src/index.js


在前面段落已经说到,IndexRouteRoute都是配置组件。从代码可以看出,App是入口组件;现在IndexRoute指定了当用户访问服务的根目录时候,会默认显示Home这个组件;当用户访问"repos"时候会显示Repos组件;在用户访问"about"时候会显示About组件;然后Repos组件下又配置了在有两个参数情况下显示Repo组件;


现在看一下App组件的代码src/components/Main.js


App作为入口组件主要要3部分组成:

  1. <h3>标题  

  2. <NavLink>导航(有兴趣的朋友可以再看一下NavLink的源码,主要是封装了react-router的<Link>组件)

  3. props.children其下层的子组件


当点击导航<NavLink>时候,路由(hashHistory)发生变化,Router监听到变化后,根据配置组件,显示出相对应的组件;

上面这句话结合redux会是这样描述:


当点击导航<NavLink>时候,路由(hashHistory)发生变化,Router监听到变化后,会触发routerReducerredux同步更新location,并且根据配置组件,显示出相对应的组件;
最后,我们看一下点击按钮(Increase、Decrease)时候,数字为什么发生变化:
毕竟是最后部分,这解释起来会比路由稍复杂。

先理一下大致思路:


你看到的现象是,点击increase,decrease按钮时候,数据发生加减变化。其实啊页面显示的数字,是store之中存放的一个数据;当点击increase,decrease按钮,触发一个redux的方法,让store之中数据发生变化,从而让你看到页面的数字发生变化!

先看一下Home组件的代码:


src/components/Home.js
先说明一下import了都是些什么东西。

react这个你懂的,不多说了(^_^);


react-reduxconnect,connect方法源于Provider组件(文章一开头有说明,这里引用一下官方文档再补充一下):


connect会把组件的state对象中的props和store的dispatch传递给根组件;connect会在组件渲染完后,给store添加订阅,当store中dispatch被调用时候,state的props会发生变化触发组件rerender;
订阅机制之中,更新state中的props逻辑主要由3个函数构成,这3个函数都由connect方法传入

connect(mapStateToProps, mapDispatchToProps, mergeToProps)(App);
第一个函数接收store中state和props,使页面可以根据当前的store中state和props返回新的stateProps;
第二个函数接收store中的dispatch和props,使页面可以复写dispatch方法,返回新的dispatchProps;
第三个函数接收前2个函数生成的stateProps和dispatchProps,在加上原始的props,合并成新的props,并传给原始根节点的props。(本项目没有使用这个参数)
引用一张图:
  1. View触发dispatch

  2. 进入reducer通过action返回值修改store中的state

  3. 将新的state和props传入handleChange中,生成更符合页面的props

  4. 传给原始根节点重新render



在这个项目之中,点击按钮然后视图数字发生变化的过程是:


变化数字是store中的state.count.number,点击Increase、Decrease按钮时候,View引发reducer的increase(或decrease)这个action触发dispatch,dispatch根据action的返回值修改了store中的state。新的state、props传入handleChange引发组件的render,更新数字。这就是整个过程。






前端圈--打造专业的前端技术会议

为web前端开发者提供技术分享和交流的平台

打造一个良好的前端圈生态,推动web标准化的发展

官网:http://fequan.com

微博:fequancom | QQ群:41378087



长按二维码关注我们

投稿:content@fequan.com

赞助合作:apply@fequan.com


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存