前端已不止于前端-ReactJs初体验
原文写于 2015-04-15 https://github.com/kuitos/kuitos.github.io/issues/21
要说2015年前端届最备受瞩目标手艺是啥,固然非ReactJs莫属。作为一个只关注最前沿前端手艺的系列,天然少不了关于它的引见。
ReactJs简介
React最初来自Facebook内部的广告体系项目,项目实行过程当中前端开辟碰到了庞大应战,代码变得愈来愈痴肥且杂沓不堪,难以保护。因而痛定思痛,他们决议抛开许多所谓的“最好实践”,从新思索前端界面的构建体式格局,因而就有了React。
React的设想依托于Facebook另一个叫做FLUX的项目,FLUX是一个为了处置惩罚Facebook在MVC运用中碰到的工程性问题而生的设想形式,重要思绪是单向数据流。剖析 Facebook 的 Flux 运用架构
React是MVC中薄薄的一层V,它只关注表现层,对组件化开辟有很大的裨益。
ReactJs中心特性
virtual dom react中的组件跟页面实在dom之间会有一层virtual dom(假造dom),virtual dom是内存中的javascript对象,它具有与实在dom一致的树状构造。开辟者每次试图更新view,react都邑从新构建virtual dom树,然后将其与上一次virtual dom树作对照,依托react强劲的中心算法dom diff找出真正发作变动的节点,末了映射到实在dom上,这也是react号称机能高效的隐秘地点。依靠于virtual dom,对React而言,每一次界面的更新都是团体更新,而不是层叠式更新(即一个庞杂的,各个UI之间能够存在相互依靠的时刻,每一次自力的更新能够会激发其他UI的变化,如果我们的目标是更新C的数据,逻辑流许多是如许的 A –>B–>C–>A–>B–>C,这类情况下中间状况的DOM操纵就是极大的糟蹋)。
单向数据流 flux架构下的数据流显现出一种单向、闭环的活动线路,使得统统行动变的可展望,也能更好的定位毛病发作点。react官方的卖点之一就是 友爱的毛病提醒(这是在针对angular么哈哈)
每一个组件都是状况机 react以为组件的数据模型是不可变的,组件的属性不该该被修正。组件关注的只应当是状况,差别的状况显现差别的表现形式。每一个状况下的组件都是一个virtual dom对象,如许react就能够直接经由过程等号对照对象地点推断组件是不是被修正从而是不是须要更新dom,这也是其能进步机能的缘由之一(空间换时候)。
组件 统统都是组件 react首倡开辟者将view切分红一个个组件从而到达松耦合及重用的目标。开辟者构建页面只须要排列组合就好了。
immutable object React首倡运用只读数据来竖立数据模型,每次更新都是new object,这也是dom diff 机能强劲的暗码地点(===即可推断两个对象是不是相称,而不须要深度遍历)。参考资料 immutable.js
JSX 不是在js内里写html,jsx是xml的javascript示意法。
说了这么多理论性的东西,照样直接来上代码吧
1. ReactJs开辟准备事情
起首你须要reactjs的开辟环境。
bower install react
剧本中引入react,因为我们须要运用jsx语法进步开辟效力,所以还须要引入能讲jsx转化为javascript的库
不过如许JSXTransformer每次都邑在app翻开的时刻做转换事情,并不合适临盆环境,转换事情应当放在服务端举行,借助jsx东西npm install -g react-tools jsx --watch src/ build/
然后页面依靠改成如许
node插件会在你开辟的时刻自动将源码转成javascript文件到指定目次
2. 第一个react递次
// Hello World
React.render(
<h1>Hello, world!</h1>,
document.getElementById('example')
);
3. 接下来我们引见一下react的一些基本语法
React.render() 将模版转换成html并插进去到指定节点 拜见上文的hello world示例
React剖析引擎的划定规矩就是碰到<标记就以jsx语法剖析,碰到{就以javascript语法剖析。比方如许
var array = [ <h1>Example 2</h1>, <h2>Hello World</h2> ]; React.render( <div>{array}</div>, document.getElementById("example2") );
经由过程检察转换后的代码,我们能够看到他摘下面具后长如许
var array = [ React.createElement("h1", null, "Example 2"), React.createElement("h2", null, "Hello World") ]; React.render( React.createElement("div", null, array), document.getElementById("example2") );
怎样建立组件
var HelloWorldComponent = React.createClass({ render: function () { return <div>React Component {this.props.author}</div>; } }); React.render( <HelloWorldComponent author="Kuitos"/>, document.getElementById("hello") );
经由过程React.createClass能够建立一个关联了假造dom的组件对象,每次组件数据更新便会挪用组件的 render 要领从新衬着dom。
组件对象的props属性
上面一个例子我们看到在组件render要领中我们能够经由过程this.props.xx的体式格局拿到组件上关联的属性。别的须要分外提到的是,this.props有一个特别属性children,它指向组件的子节点鸠合,like thisvar List = React.createClass({ render: function () { return ( <ol> { this.props.children.map(function (child) { return <li>{child}</li> }) } </ol> ); } }); React.render( <List> <a href="#">百度</a> <a href="#">谷歌</a> </List>, document.getElementById("example3") );
页面衬着的结果就是一个 ol 列表中另有两个li,每一个li中包括一个超链接。经由过程这里我们也能够看出,在jsx中{}是会getValue的
猎取实在dom React.findDOMNode()
var counter = 0; var Button = React.createClass({ handleClick: function () { React.findDOMNode(this.refs.input).focus(); }, render: function () { return ( <div> <input type="text" ref="input"/> <input type="button" value="counter" onClick={this.handleClick}/> </div> ); } }); React.render( <Button />, document.getElementById("button") );
组件状况 this.state
var Toggle = React.createClass({ getInitialState: function () { return {liked: false}; }, handleClick: function (event) { this.setState({liked: !this.state.liked}); }, render: function () { var text = this.state.liked ? "like" : "unlike"; return ( <p onClick={this.handleClick}> U {text} this. </p> ); } }); React.render( <Toggle />, document.getElementById("button1") );
用React的体式格局完成angular中双向绑定的结果
var Input = React.createClass({ getInitialState: function () { return {value: "Kuitos"}; }, handleChange: function (event) { this.setState({value: event.target.value}); }, render: function () { var value = this.state.value; return ( <div> <p>{value}</p> <input type="text" value={value} onChange={this.handleChange}/> </div> ); } }); React.render( <Input/>, document.getElementById("inputDataBind") );
virtual dom状况变动回调
组件生命周期分为三个状况:Mouting: 已插进去实在 DOM
Updating: 正在被从新衬着
Unmounting: 已移出实在 DOM
React为每一个状况都供应响应的pre跟post处置惩罚函数。只不过React的定名是will(pre 进入状况之前)跟did(post 进入状况以后)。
componentWillMount()
componentDidMount()
componentWillUpdate(Object nextProps, Object nextState)
componentDidUpdate(Object prevProps, Object prevState)
componentWillUnmount()
我们如许写var Input = React.createClass({ getInitialState: function () { return {firstName: "Kuitos", lastName: "Lau"}; }, handleChange: function (event) { this.setState({firstName: event.target.value}); }, componentWillMount: function () { console.log("dom will be insert", this.state.firstName); }, componentDidMount: function () { console.log("dom had be insert", this.state.firstName); }, componentWillUpdate: function (nextProps, nextState) { console.log("dom will be update", nextProps, nextState); }, componentDidUpdate: function (prevProps, prevState) { console.log("dom had be update", prevProps, prevState); }, render: function () { var state = this.state; return ( <div> <p>{state.firstName} {state.lastName}</p> <input type="text" value={state.firstName} author={state.firstName} onChange={this.handleChange}/> </div> ); } }); React.render( <Input/>, document.getElementById("inputDataBind") );
打印的递次依次是,dom will be update , dom had be update
当input输入时 dom will be update , dom had be update
react的基本知识就引见到这里,后续我们会继承引见react在实战项目中的运用及react native在挪动端的表现力。