初步尝试使用React+Redux来开发,将从以下几个方面记录:React基础,Redux基础,React Router基础,项目组件结构,遇到问题,React与Vue的props,React与Vue的组件通信。
React基础
JSX
JSX能定义简洁且我们熟知的包含属性的树状结构语法。
JSX 把类 XML 的语法转成纯粹 JavaScript,XML 元素、属性和子节点被转换成 React.createElement 的参数。
详见或手动http://www.css88.com/react/docs/jsx-in-depth.html
组件的生命周期
state与props
详见或手动http://www.cnblogs.com/ZSG-DoBestMe/p/5293457.html
Redux基础
以下引自lovesuu的文章,感谢。
上面这张图,在展现单向数据流的同时,还为我们引出了几个熟悉的模块:Store、Actions、Action Creators、以及Views。
相信大家都不会陌生,因为它们就是Flux设计模式中所提到的几个重要概念,在这里,Redux沿用了它们,并在这基础之上,又融入了两个重要的新概念:Reducers和Middlewares。
Actions
问题:action is not defined
import * as actions from '../../actions/home';
需要按照上图步骤,在action中定义方法并暴露出来,将相关action.type同步到reducer
Store
当系统中有很多的模型和相应的视图特别是模型和视图间可能存在的双向数据流动时,其复杂度就会迅速扩大,非常难以理解和调试。React与Redux通过store来实现单向数据流。
store 是一个单一对象:
管理应用的 state
通过 store.getState() 可以获取 state
通过 store.dispatch(action) 来触发 state 更新
通过 store.subscribe(listener) 来注册 state 变化监听器
通过 createStore(reducer, [initialState]) 创建
Action Creators
“redux里面可以不用action creators”,那么action creators是什么呢?Action Creator 意思是动态去生成Action,在Redux里面即bindActionCreators。
midware实现异步
问题:Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.
dispatch(action) 是一个同步的过程:执行 reducer 更新 state -> 调用 store 的监听处理函数。如果需要在 dispatch 时执行一些异步操作(fetch action data),可以通过引入 Middleware 解决。
它提供的是位于 action 被发起之后,到达 reducer 之前的扩展点。 你可以利用 Redux middleware 来进行日志记录、创建崩溃报告、调用异步接口或者路由等等。
Reducers
在Actions里面触发,Reducers通过action.type来改变Store
React Router基础
它是官方维护的,事实上也是唯一可选的路由库。它通过管理 URL,实现组件的切换和状态的变化,开发复杂的应用几乎肯定会用到。
详见或手动http://www.ruanyifeng.com/blog/2016/05/react_router.html?utm_source=tool.lu
遇到问题
ie下constructor中this失效
开发移动端页面是遇到这个问题
问题:
react在contructor里访问props,如果通过this.props.xxxx的方式访问在IE下会存在问题,只能通过contructor的形参props去访问:
contructor(props){
super(props);
var xx = props.xxx; // 没问题
var xx = this.props.xxx; //有问题,props为undefined
}
原因
ie10 以下的 super有问题,解决方案可以使用presets: [‘stage-0’, ‘es2015-ie’, ‘react’]做兼容。具体原因见:链接或手动https://github.com/babel/babel.github.io/blob/492dad8dabfd7326015a5f44157b624e0dde8302/docs/usage/caveats.md#classes-10-and-below
解决方案
安装插件
"babel-plugin-add-module-exports": "~0.1.2",
"babel-plugin-transform-es2015-classes": "^6.8.0",
"babel-plugin-transform-class-properties": "^6.5.2",
"babel-plugin-transform-es3-member-expression-literals": "^6.8.0",
"babel-plugin-transform-es3-property-literals": "^6.8.0",
"babel-plugin-transform-object-assign": "~6.5.0",
"babel-plugin-transform-proto-to-assign": "^6.8.0",
"babel-plugin-transform-react-display-name": "~6.5.0",
React与Vue的props
React中的props
- props的改变是全局性的,不分父到子和子到父
Vue中的props
- “prop” 是组件数据的一个字段,期望从父组件传下来。子组件需要显式地用 props 选项 声明 props:
props: [
‘item’
] - prop 默认是单向绑定:当父组件的属性变化时,将传导给子组件,但是反过来不会。这是为了防止子组件无意修改了父组件的状态。不过,也可以使用 .sync 绑定修饰符显式地强制双向或单次绑定。
React与Vue的组件通信
React通过生命周期中的方法
- 在生命周期处理this.props,nextProps
Vue通过父子组件通信
- 子组件可以用 this.
parent访问它的父组件。父组件有一个数组this. children,包含它所有的子元素。 -
这让父组件与子组件紧密地耦合,Vue 实例实现了一个自定义事件接口,用于在组件树中通信。这个事件系统独立于原生 DOM 事件,做法也不同。
每个 Vue 实例都是一个事件触发器:
- $on() 监听事件
- $emit() 在Vue 实例上面触发事件;
$broadcast() 广播事件,事件向下传导给所有的后代。
-
$dispatch() 派发事件,事件沿着父链冒泡;
以点击侧栏主面板响应为例,在子组件export default中,书写
methods:{
selectNav(event){
this.$dispatch('selectNav',event.target.innerHTML)
},
}在父组件 export default中,书写
events:{
selectNav(title){
...
}
}由此实现了子模板到父模板的数据传递和事件触发,达到了主面板响应的目的
经过初步实践,这样的传递数据和父子组件通信,给开发者的感觉是思维清晰,容易上手,必要的组件分割不因为依赖束手束脚~