React-引领未来的用户界面开发框架-读书笔记(一)
第1章 react简介1.本质上是一个状态机,它以精简的模型管理复杂的随着时间而变化的状态。 2.它不是model-view-controller,它是mvc中的v(view),用来渲染视图。 3.React运用虚拟的dom实现了一个强大的渲染系统。 4.(1)React就像高性能3d游戏引擎,以渲染函数为基础。这些函数读入当前的状态,将其转换为目标页面上的一个虚拟表现。只要react被告知状态有变化,它就会重新运行这些函数,计算页面的一个新的虚拟表现,接着自动化把结果转换成必要的dom更新来反应新的表现。 4.(2)乍一看,这种方式应该比通常的javascript方案(按需更新每一个元素要慢),但react确实是这么做的:它是用了非常高效的算法,计算出虚拟页面当前版本和新版间的差异,基于这些差异对dom进行必要的最少更新。 5.所以说react赢就赢在了:
6.react的虚拟表示差异算法,不但能够把这些问题的影响降到最低。 ,还能简化应用的维护成本。当用户输入或者有其他更新导致状态改变时,我们只要简单的通知react状态改变了,它就能自动化地处理剩下的事情。我们无须深入到详细的过程之中。 7.react在整个应用中只使用单个事件处理器,并且会把所有的事件委托到这个处理器上。这一点也提升了react的性能。因为如果有很多时间处理器也会导致性能问题。 第2章 JSX什么是JSXJSX即JavaScript XML——一种在React组件内部构建标签的类XML语法。 与以往在JavaScript中嵌入HTML标签的几种方案相比,JSX有如下几点明显的特征:
React.DOM.h1({className: 'question'},'Question'); // v0.11
React.createElement('h1',{className: 'Question'); // v0.12
使用JSX之后 <h1 className="question">Queations</h1>;
使用JSX的好处
定义一个自定义组件const React = require('react');
const ReactDOM = require('react-dom');
class Divider extends React.Component {
render() {
return (
<div classNams="divider">
<h2>Questions</h2><hr/>
</div>
)
}
}
ReactDOM.render(
<Divider></Divider>,document.getElementById('init')
);
使用动态值JSX将两个花括号之间的内容{。。。}渲染为动态值。 简单值: var text = "Questions"
class "divider">
<h2>{text}<'init')
);
复杂逻辑使用函数求值: class Date extends Component {
dataToString = (d) => {
return [
d.getFullYear(),d.getMonth + 1,d.getDate()
].join('-')
}
render() {
return (
<h2>{this.dataToString(new Date())}</h2>
)
}
}
ReactDOM.render(
<Date></Date>,51)"> react通过将数组中的每一个元素渲染为一个节点的方式对数组进行自动求值。
使用三目运算符render(){
return(
<div className={
this.state.isComplete ? 'is-complete' : ''
}>...</div>
)
}
使用变量getIsComplete = () => {
return this.state.isComplete ? '';
}
render(){
var isComplete = this.getIsComplete();
return(
<div className={isComplete}>...</div>
)
}
使用函数'';
}
render(){
return(
<div className={this.getIsComplete()}>...</div>
)
}
使用逻辑与(&&)运算符render(){
return(
<div className={this.state.isComplete && 'is-complete'}>...</div>
)
}
非dom属性值key
ref
render () {
return (<div>
<input ref="myInput" .../>
</div>);
}
接着就可以在组件中的任何地方使用this.refs.myInput获取这个引用了(不是真实的dom,是react在需要时用来创建dom的一个描述对象。若要访问真实的节点,则可以使用:this.refs.myInput.getDOMNode() ) dangerouslySetInnerHTML(随时可能发生变化)render () {
var htmlString = {
__html: "<span>an html string</span>"
}
return (
<div dangerouslySetInnerHTML={htmlString}></div>
);
}
事件在jsx中,捕获一个事件就像给组件的方法设置一个属性一样简单。 handleClick = (event) => {
//...
}
render () {
return (
<div onClick={this.handleClick.bind(this)}></div>
);
}
注释jsx的本质就是javascript,所以可以在标签内添加原生的js注释。 注释可以用以下2种形式添加:
1.作为子节点: <!-- 子节点形式的注释只需要简单地包裹在花括号内即可,并且可以跨多行。-->
<div>
{
/* 这是注释内容 */
}
<input type="text" name="" value="" placeholder="">
</div>
2.作为内联属性 // 内联的注释可以有两种形式。首先,可以使用多行注释:
<div>
<input /* 这是多行注释内容! */ type="text" placeholder="address" />
</div>
// 其次也可以使用单行注释
<div>
<input type="text" // 这是单行注释 placeholder="address" />
</div>
特殊属性
<label htmlFor="for-text" ...>
<div className={classes} ...>
样式简单的驼峰属性命名即可 render () {
var styles = {
borderColor: "#888",borderThinkness: "1px"
};
return (
<div style={styles}></div>
);
}
如果需要添加浏览器前缀瑞 -webkit-、-ms- 大驼峰(除了 ms ),如: var divStyle = {
WebkitTransition: 'all',// 'W' 是大写
msTransition: 'all' 'ms' 为小写
};
没有jsx的react所有的jsx标签最后都会被转换为原生的javascript。因此jsx对于react来说并不是必需的。然而,jsx确实减少了一部分复杂性。如果你不打算在react中使用jsx,那么在react中创建元素时需要知道以下三点:
page 19. 第3章 组件的生命周期React为每个组件提供了生命周期钩子函数去响应不同的时刻:
生命周期方法react组件以简洁的生命周期api来单单提供你所需要的方法(而不是所有方法)。 实例化一个实例初次被创建所调用的生命周期方法和其他各个后续实例被创建时所调用的方法略有不同。 所以:当你首次使用一个组件类时,有如下调用顺序:
而该组件类的所有后续应用,将会如下:
??区别在于后续的不必执行:getInitialState函数,其余函数如常。(有待进一步理解)
App extends Component {
constructor(props) {
super(props);
this.state = {};
}
...
}
Class Component {
constructor(props) {
super(props);
}
state = {}
...
}
存在期随着应用状态的改变,以及组件逐渐受到影响,依次调用如下方法:
销毁&清理期最后,组件被使用完后,componentWillUnmount方法将会被调用,目的是给这个实例提供清理自身的机会。 接下来,应该具体的理解 p24~30的内容(各个时期的各个函数的具体运作)。这里不过多阐述以增加篇幅,只理清思路即可。 我认为这段内容,应该是react的第一块关键内容,乃设计之精心之处,应多多揣摩,烂熟于胸。 由于原书的内容是基于ES5的,下面的章节对使用ES6时的生命周期进行讲解: 第二章 - ES6版 React组件生命周期小结下面所写的,只适合前端的React。(React也支持后端渲染,而且和前端有点小区别,不过我没用过。) 相关函数简单地说,React Component通过其定义的几个函数来控制组件在生命周期的各个阶段的动作。 在ES6中,一个React组件是用一个class来表示的(具体可以参考官方文档),如下: // 定义一个TodoList的React组件,通过继承React.Component来实现
class TodoList extends Component {
...
}
这几个生命周期相关的函数如下: constructor(props,context) 构造函数,在创建组件的时候调用一次。 componentWillMount() 在组件挂载之前调用一次。如果在这个函数里面调用setState,本次的render函数可以看到更新后的state,并且只渲染一次。 componentDidMount() 在组件挂载之后调用一次。这个时候,子主键也都挂载好了,可以在这里使用refs。 componentWillReceiveProps(nextProps) props是父组件传递给子组件的。父组件发生render的时候子组件就会调用componentWillReceiveProps(不管props有没有更新,也不管父子组件之间有没有数据交换)。 shouldComponentUpdate(nextProps,nextState) 组件挂载之后,每次调用setState后都会调用shouldComponentUpdate判断是否需要重新渲染组件。默认返回true,需要重新render。在比较复杂的应用里,有一些数据的改变并不影响界面展示,可以在这里做判断,优化渲染效率。 componentWillUpdate(nextProps,51)"> shouldComponentUpdate返回true或者调用forceUpdate之后,componentWillUpdate会被调用。
|