React是一个主要用于构建用户界面的JavaScript库,相比传统型的前端开发,React开辟了一个相当另类的途径,实现了前端界面的高效率高性能开发。可以从以下几点来对它进行初步的了解:
- React 起源于Facebook对市场上所有JavaScript MVC框架的不满[2013年5月开源]。
- React 本身并不是一个MVC框架,顶多算是其中的V(View)。
- React 官方推荐使用JSX,但没有JSX的React也能工作。
- React 的服务器端Render能力只能算是一个锦上添花的功能,并不是其核心出发点。
- React 拥有的虚拟DOM让页面渲染变得非常的高效,并且比直接操作DOM更为可控。(******)
- React 可以让我们通过分割组件的方式去开发复杂的页面或某个功能区块,并且组件是可以被复用的,也即可以进行组件驱动开发。(******)
- React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。
React的入门学习可以这么来:
1.前期知识储备
进行React学习之前,需要具备Html、CSS和JavaScript的基础知识,并对JSX有一定的了解。
2.开发环境/安装
React 可以直接下载使用,下载包中也提供了很多学习的实例。(http://facebook.github.io/react/ )
除此之外,也可以直接使用 BootCDN 的 React CDN 库。
3.常用语法
- ReactDOM.render 是 React 的最基本方法,用于将模板转为 HTML 语言,并插入指定的 DOM 节点。[如果代码中嵌套多个 HTML 标签,就使用一个标签元素包裹它,否则会报错。]
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('example')
);
- 样式渲染:React 可以渲染 HTML 标签 (strings) 和 React 组件 (classes)。[原生 HTML 元素名必须以小写字母开头,而自定义的 React 类名必须以大写字母开头]
/*要渲染 HTML 标签,只需在 JSX 里使用小写字母的标签名。 */
var myDivElement = <div className="foo" />;
ReactDOM.render(myDivElement, document.getElementById('example'));
/*要渲染 React 组件,只需创建一个大写字母开头的本地变量。*/
var MyComponent = React.createClass({/*...*/});
var myElement = <MyComponent someProperty={true} />;
ReactDOM.render(myElement, document.getElementById('example'));
- 注释:在标签内部的注释需要花括号,在标签外的的注释不能使用花括号。
ReactDOM.render(
/*注释 */
<h1>孙朝阳 {/*注释*/}</h1>,
document.getElementById('example')
);
- 数组:JSX 允许在模板中插入数组,数组会自动展开所有成员。
var arr = [
<h1>哈喽哈喽哈喽</h1>,
<h2>哈喽哈喽</h2>,
<h3>哈喽</h3>,
];
ReactDOM.render(
<div>{arr}</div>,
document.getElementById('example')
);
- 组件:React.createClass() 方法用于生成一个组件类。
var HelloMessage = React.createClass({
render: function() {
return <h1>Hello World!</h1>;
}
});
ReactDOM.render(
<HelloMessage />,/*实例组件类并输出信息*/
document.getElementById('example')
);
- 复合组件:通过创建多个组件来合成一个组件,即把组件的不同功能点进行分离。
var WebSite = React.createClass({
render: function() {
return (
<div>
<Name name={this.props.name} />
<Link site={this.props.site} />
</div>
);
}
});
var Name = React.createClass({
render: function() {
return (
<h1>{this.props.name}</h1>
);
}
});
var Link = React.createClass({
render: function() {
return (
<a href="{this.props.site}">
{this.props.site}
</a>
);
}
});
{this.props.site}
</a>
);
}
});
- 状态:React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。getInitialState 方法用于定义初始状态,也就是一个对象,这个对象可以通过 this.state 属性读取,状态变化时可以使用this.setState 方法修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件。
var LikeButton = React.createClass({
getInitialState: function() {
return {liked: false};
},
handleClick: function(event) {
this.setState({liked: !this.state.liked});
},
render: function() {
var text = this.state.liked ? '喜欢' : '不喜欢';
return (
<p onClick={this.handleClick}>
你<b>{text}</b>我。点我切换状态。
</p>
);
}
});
ReactDOM.render(
<LikeButton />,
document.getElementById('example')
);
- 属性:state 和 props 主要的区别在于 props 是不可变的,子组件只能通过 props 来传递数据。getDefaultProps() 方法用于设置 props 的默认值,通过 this.props 来获取数据。
var HelloMessage = React.createClass({
getDefaultProps: function() {
return {
name: 'Runoob'
};
},
render: function() {
return <h1>Hello {this.props.name}</h1>;
}
});
ReactDOM.render(
<HelloMessage />,
document.getElementById('example')
);
- React 组件 API:
- 设置状态:setState setState(object nextState[, function callback]) 合并nextState和当前state,并重新渲染组件。
- 替换状态:replaceState replaceState(object nextState[, function callback]) replaceState()方法与setState()类似,但是方法只会保留nextState中状态,原state不在nextState中的状态都会被删除。
- 设置属性:setProps setProps(object nextProps[, function callback]) 设置组件属性,并重新渲染组件。
- 替换属性:replaceProps replaceProps(object nextProps[, function callback]) replaceProps()方法与setProps类似,但它会删除原有props
- 强制更新:forceUpdate forceUpdate([function callback]) forceUpdate()方法会使组件调用自身的render()方法重新渲染组件,组件的子组件也会调用自己的render()。但是,组件重新渲染时,依然会读取this.props和this.state,如果状态没有改变,那么React只会更新DOM。forceUpdate()方法适用于this.props和this.state之外的组件重绘(如:修改了this.state后),通过该方法通知React需要调用render()。一般来说,应该尽量避免使用forceUpdate(),而仅从this.props和this.state中读取状态并由React触发render()调用。
- 获取DOM节点:findDOMNode DOMElement findDOMNode() 返回 DOM元素DOMElement
- 判断组件挂载状态:isMounted bool isMounted() 返回 true或false,表示组件是否已挂载到DOM中
- React Ajax:React 组件的数据可以通过 componentDidMount 方法中的 Ajax 来获取,当从服务端获取数据库可以将数据存储在 state 中,再用 this.setState 方法重新渲染 UI。当使用异步加载数据时,在组件卸载前使用 componentWillUnmount 来取消未完成的请求。
var UserGist = React.createClass({
getInitialState: function() {
return {
username: '',
lastGistUrl: ''
};
},
componentDidMount: function() {
this.serverRequest = $.get(this.props.source, function (result) {
var lastGist = result[0];
this.setState({
username: lastGist.owner.login,
lastGistUrl: lastGist.html_url
});
}.bind(this));
},
componentWillUnmount: function() {
this.serverRequest.abort();
},
render: function() {
return (
<div>
{this.state.username} 用户最新的 Gist 共享地址:
<a href={this.state.lastGistUrl}>{this.state.lastGistUrl}</a>
</div>
);
}
});
ReactDOM.render(
<UserGist source="https://api.github.com/users/octocat/gists" />,
mountNode
);
- React Refs:React 支持一种非常特殊的属性 Ref ,它可以用来绑定到 render() 输出的任何组件上。这个特殊的属性允许你引用 render() 返回的相应的支撑实例( backing instance )。这样就可以确保在任何时间总是拿到正确的实例。
<input ref="myInput" />
var input = this.refs.myInput;
var inputValue = input.value;
var inputRect = input.getBoundingClientRect();
4.总结
如前所述,React的优点有很多,但如果需要在项目中使用,仍需要先考虑其兼容性。React兼容IE9及其以上浏览器,针对IE8,可以通过对其进行修改、添加JS文件来解决部分问题。如果兼容性合适,那么在Web项目中使用React之前,也需要进行适当的实践。