前言
上周用了一个礼拜,了解了react的理论知识,依然一头雾水;
本周直接参照项目代码,真正着手去写项目模块,终于能正式把react中的数据串通;
目录
- 工具 & 准备
- dva项目框架结构
- dva框架下的react项目的数据流通
- 学习资料推荐
- 总结
1. 工具 & 准备
dva-cli框架
dva结构介绍
dva 官方中文文档
使用 dva 所需的所有知识点
在react的发展过程中,比较主流的几个框架从flux,发展到redux,在这些的基础上,dva-cli这一个脚手架工具,帮助我们更加轻松地完成react开发,而其完成的部分,就是为一个项目的逻辑、数据、页面,提供了一个很好的划分、管理、组织、通信的系统。
点击此处查看更详细的介绍:《dva搭建简易react项目实践总结》
2. dva项目框架结构
react项目的推荐目录结构(如果使用dva脚手架创建,则自动生成如下)
|── /mock/ # 数据mock的接口文件
|── /src/ # 项目源码目录(我们开发的主要工作区域)
| |── /components/ # 项目组件(用于路由组件内引用的可复用组件)
| |── /routes/ # 路由组件(页面维度)
| | |── route1.js
| | |── route2.js # 根据router.js中的映射,在不同的url下,挂载不同的路由组件
| | └── route3.js
| |── /models/ # 数据模型(可以理解为store,用于存储数据与方法)
| | |── model1.js
| | |── model2.js # 选择分离为多个model模型,是根据业务实体进行划分
| | └── model3.js
| |── /services/ # 数据接口(处理前台页面的ajax请求,转发到后台)
| |── /utils/ # 工具函数(工具库,存储通用函数与配置参数)
| |── router.js # 路由配置(定义路由与对应的路由组件)
| |── index.js # 入口文件
| |── index.less
| └── index.html
|── package.json # 项目信息
└── proxy.config.js # 数据mock配置
index.js文件介绍
// 引入dva库
import dva from 'dva';
// 引入dva的路由库
import { useRouterHistory, browserHistory, hashHistory } from 'dva/router';
// 初始化,创建dva实例
const app = dva({history: browserHistory});
// 使用插件
app.use(Hooks)
// 在index.js中注册models文件夹下的所有用到的model
// 之前提到过,redux的一大原则就是唯一数据源,即单个应用内只有一个store,状态是一个树形对象
// 功能不同的业务实体分别挂在到这一唯一store下,是二级元素
// 注册后才能将model1、model2、model3中的state与函数等属性,挂载到全局唯一的store中去
app.model(require('./models/model1'));
app.model(require('./models/model2'));
app.model(require('./models/model3'));
// 注册路由文件
app.router(require('./router'));
// 将dva实例绑定到DOM树中的#root元素,意为所有的react-Dom都加载于root节点下
app.start('#root');
router.js文件介绍
包含应用中的路由映射,url ==> 路由组件route
import React, { PropTypes } from 'react';
import { Router, Route, IndexRoute, IndexRedirect } from 'dva/router';
import App from './routes/App';
import Login from './routes/Login';
export default function({ history }) {
return (
<Router history={history}>
<Route path={`/`} component={App}>
// 添加一级子路由
<IndexRoute component={Login} /> // 指定默认首页页面
<Route path={`login`} component={Login} />
<Route path={`route1`} component={route1} />
// 添加二级子路由
<Route path={`route1/subroute`} component={route1} />
<Route path={`route2`} component={route2} >
<Route path={`route3`} component={route3} />
</Route>
</Route>
</Router>
);
};
3. dva框架下的react项目的数据流通
步骤注解:
1.项目入口文件:index.js
2.根据浏览器中访问的url到router.js中查找对应的Route组件,完成初始的页面渲染
3.在组件被初始渲染时,依次调用以下方法:
当组件在客户端被实例化,第一次被创建时,以下方法依次被调用:
1、getDefaultProps // 获取默认props值,对于每个组件实例来讲,这个方法只会调用一次
2、getInitialState // 获取初始私有state
3、componentWillMount // 在组件生成前执行其中的方法
4、render // 组件渲染
5、componentDidMount // 组件生成后调用其中的方法
//在componentDidMount函数执行时,已经渲染出真实的DOM,可以通过this.refs.[refName]获取真实DOM
在选择性完成以上几个生命钩子后,组件已经正式渲染完成,可以与用户完成交互
4.可以为渲染出的React-DOM元素绑定交互事件,将用户的请求转为dispatch,通过dispatch对象到对应的model中寻找effects方法;
// 以点击事件为例
// 点击后,通过全局唯一的dispatch对象,向model层派发一个action
onclick = () => {
const dispatch = this.props.dispatch; // 获取全局的派发对象 dispatch
dispatch({
type: 'model1/effect1', // type: 在名为'model1'的数据模型中查找effects属性中的'effect1'函数
payload: { key: value } // payload:传入当前type的参数对象
})
}
5.组件完成渲染后,组件处于存在期,当因为用户的操作或其他,导致与当前组件绑定的model.state或组件内的state发生改动时,会依次调用以下方法,对组件进行重新渲染(此轮步骤可多次循环):
1、componentWillReceiveProps // 当前组件绑定的model.state或组件内的state发生改动时,调用其中方法
2、shouldComponentUpdate // 判断是否进行重新渲染
3、componentWillUpdate // 在组件接收到了新的 props 或者 state 即将进行重新渲染前,执行
4、render // 重新渲染
5、componentDidUpdate // 组件重新渲染之后调用
6.切换url时,对应的路由组件随之更换,组件被销毁,在组件销毁前执行以下操作:
componentWillUnmount // 在组件销毁之前执行,比如用于解绑事件监听、计时器等
4. 学习资料:
以下介绍的教程,我个人觉得知识点有些细,比较适合用于后期巩固查露的,前期可以跟着网上的项目着手去实践,后期再来了解具体原理
阮一峰React教程
使用 dva 所需的所有知识点
总结
对于react的学习最大的感悟就是要在实践中,梳理数据流通的路径,当熟练了这一个流通路径之后,剩余的就是一个数据读取与写入的劳动。
也是通过这一次操作,体会到了传说中的React的数据流通的“复杂性”,确实相对于Vuex来说,缺少了双向绑定,但是React的优势就是在于数据的高效单向传输,以及DOM的高效渲染。
每一个工具都有它的独特性,多练就能体会到它的好用。
在写这篇笔记时,距离笔记中所记录的初次实践已经过去了两个礼拜,在期间也遇到了无数的技术问题,努力踩坑中......