React学习(8)—— 高阶应用:不使用ES6、JSX实现React
不使用ES6通常情况下,定义一个React组件可以使用ES6规范中的class关键字: class Greeting extends React.Component { render() { return <h1>Hello,{this.props.name}</h1>; } } 如果不使用ES6语法,可以直接使用 var Greeting = React.createClass({ render: function() { return <h1>Hello,{this.props.name}</h1>; } }); 声明Prop的检查类型以及默认Props值在前面的博文(prop类型检查与真实Dom操作)中介绍了如何规约Prop的参数值,给出的例子都是用ES6实现的: class Greeting extends React.Component { // ... } Greeting.propTypes = { name: React.PropTypes.string }; Greeting.defaultProps = { name: 'Mary' }; 在使用 var Greeting = React.createClass({ propTypes: { name: React.PropTypes.string },getDefaultProps: function() { return { name: 'Mary' }; },// ... }); 设定初始化状态在ES6的 class结构中,我们可以在构造函数中设定初始化状态: class Counter extends React.Component { constructor(props) { super(props); this.state = {count: props.initialCount}; } // ... } 在使用 var Counter = React.createClass({ getInitialState: function() { return {count: this.props.initialCount}; },// ... }); 自动绑定当使用ES6的 class 关键字声明一个React组件时,类中的方法遵循与常规的方法一样的定义。这就意味着在类中申明的方法在执行时并不会自动属于当前实例,必须在构造函数中显示的使用.bind(this)方法绑定到当前实例: class SayHello extends React.Component { constructor(props) { super(props); this.state = {message: 'Hello!'}; // 必须,否在在handleClick中this将指向调用对象 this.handleClick = this.handleClick.bind(this); } handleClick() { alert(this.state.message); } render() { return ( <button onClick={this.handleClick}> Say hello </button> ); } } 在使用 var SayHello = React.createClass({ getInitialState: function() { return {message: 'Hello!'}; },handleClick: function() { alert(this.state.message); },render: function() { return ( <button onClick={this.handleClick}> Say hello </button> ); } }); 以上的特性意味着使用ES6编写代码每一个方法都会额外增加一些样板式代码,但是对于大型应用来说代码结构更清晰。 如果十分排斥样板式代码,可以启用Babal的 类属性功能(Class Properties),利用双箭头来创建方法: class SayHello extends React.Component { constructor(props) { super(props); this.state = {message: 'Hello!'}; } handleClick = () => { alert(this.state.message); } render() { return ( <button onClick={this.handleClick}> Say hello </button> ); } } 需要注意的是,目前这个功能还是实验性的,双箭头的表达式很有可能会调整。该提议不一定会被委员会接纳。 如果非常想要尝试这种写法,你可以有这几种实现方式:
代码混合器
某些时候2个不同的组件需要共享一些相同的方法或者功能。这种情况我们称为 横切关联(cross-cutting concerns)。 一个通用的案例是一个组件需要定期更新自己的状态,只要使用 // 定义一个混合器 var SetIntervalMixin = { //组件将要被渲染时调用 componentWillMount: function() { this.intervals = []; },// 设置定时器方法 setInterval: function() { this.intervals.push(setInterval.apply(null,arguments)); },//组件将要被卸载时调用 componentWillUnmount: function() { this.intervals.forEach(clearInterval); } }; var TickTock = React.createClass({ mixins: [SetIntervalMixin],// 设定混合器 getInitialState: function() { return {seconds: 0}; },componentDidMount: function() { this.setInterval(this.tick,1000); // 调用混合器中的setInterval 方法 },tick: function() { this.setState({seconds: this.state.seconds + 1}); },render: function() { return ( <p> React has been running for {this.state.seconds} seconds. </p> ); } }); ReactDOM.render( <TickTock />,document.getElementById('example') ); 如果组件使用了多个混合器并且很多混合器定义了相同的生命周期方法,比如同时定义了componentWillUnmount方法当组件卸载时注销某些资源。所有混合器的生命周期方法都会被调用,React会按照混合器设定的顺序来执行。 不使用JSX对于React来说JSX并不是必须要使用的表达式。当在环境中不想在家额外的编译工具时尤其适用。 每一个JSX的元素都仅仅是 例如下面使用JSX编码的例子: class Hello extends React.Component { render() { return <div>Hello {this.props.toWhat}</div>; } } ReactDOM.render( <Hello toWhat="World" />,document.getElementById('root') ); 如果我们不想使用JSX,可以将其修改为: class Hello extends React.Component { render() { return React.createElement('div',null,`Hello ${this.props.toWhat}`); } } ReactDOM.render( React.createElement(Hello,{toWhat: 'World'},null),document.getElementById('root') ); 如果你对JSX如何转换成JavaScript有很强的兴趣,可以打开这个在线编译器试试:the online Babel compiler。 组件被编译成一段字符串、由 如果对编码时每次都要键入长长React.createElement感到痛苦,一个常见的模式是分配一个别名: const e = React.createElement; ReactDOM.render( e('div','Hello World'),document.getElementById('root') ); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- swift – 当调用UIActivityViewController时,IOS 8 iPad应用
- ajax – 从JQuery向Web API发布POST时出现问题
- 如何在Swift3中获取Json包的内容(unwrap Json package)
- 如何查看任意oracle会话正在使用的事务隔离级别
- ruby-on-rails – 如何使用CanCan与gem控制器?
- arm remap
- Postgresql中的分组函数(group by 和 having)
- c# – 使用Web API的ASP.Net核心路由
- cocos2dx 实现文字的一键复制功能(IOS、Android)
- Vue引入sass并配置全局变量的方法