React在ES6中的用法

写在前面

不管是多么不乐意待见这个不速之客,但ES6已经一点点渗透进了我的生活里,就连我最爱的React到React Native,默认都把ES6做为首选标准。这是FaceBook有计划、有声势地要把ES6推起来,请问还有谁有狗胆站住来堵着路不走。所以我毅然捧着阮一峰老师的《ES6标准入门》在一旁看了起来……那好,今天就谈谈如何把React用ES6愉快地跑起来。

入门级Demos

先来几个简单的demo体验一把。注意,例子里ES5的require请通过browserfiy或webpack来实现,如果你还不会用这两样东西,请出门后往前看。

“Hello,XXX”输出

ES5写法:

var React = require('react');

var HelloMessage = React.createClass({
    render: function() {
        return (<h1>Hello,{this.props.name}!</h1>);
    }
});

module.exports = React.createClass({
    render: function() {
        return (
            <div>
                <HelloMessage name = "John" />
            </div>
        );
    }
});

ES6写法:

import React,{Component} from 'react';
class HelloMessage extends Component{
  constructor() {
    super();
  }
  render(){
    return <h1>Hello {this.props.name}</h1>;
  }
}
class Output extends Component{
  constructor() {
    super();
  }
  render(){

    return (
      <div>
          <HelloMessage name="John" />
      </div>
    );
  }
}
export default Output;

数组遍历显示

ES5写法:

var React = require('react');
var RepeatArray = React.createClass({
    render: function() {
        var names = ['Alice', 'Emily', 'Kate'];
        var arrs = [
            <h1>Hello World</h1>,
            <h2>React is awesome</h2>
        ];
        return (
            <div>
            {arr}
            {
                names.map(function (name) {return <div>Hello, {name}!</div>;});     
            }
            </div>
        );
    }
});

module.exports = RepeatArray;

ES6写法:

import React,{Component} from 'react';
class RepeatArray extends Component{
  constructor() {
    super();
  }
  render(){
    var arr = [
      <h1>Hello world!</h1>,
      <h2>React is awesome</h2>,
    ];
    var names = ['Alice', 'Emily', 'Kate'];
    return (
      <div>
      {arr}
      {
        names.map((name) =>{return <div>Hello, {name}!</div>;} )
      }
      </div>
    );
  }
}
export default RepeatArray;

ol与li的实现

ES5写法:

var React = require('react');
var RepeatLi = React.createClass({
    render: function() {
        return(
            <ol>
                {
                    this.props.children.map(function(child) {
                        return <li>{child}</li>;
                    });
                }
            </ol> 
        );
    }
});
module.exports = React.createClass({
    render: function() {
        return (
            <div>
                <RepeatLi>
                    <span>hello</span>
                    <span>world</span>
                </RepeatLi>
            </div>
        );
    }
});

ES6写法:

import React,{Component} from 'react';
class RepeatLi extends Component{
  render(){
    return (
      <ol>
      {
        this.props.children.map((child)=>{return <li>{child}</li>})
      }
      </ol>
    );
  }
}
class RepeatArray extends Component{
  constructor() {
    super();
  }
  render(){
    return (
      <div>

      <RepeatLi>
        <span>hello</span>
        <span>world</span>
      </RepeatLi>

      </div>
    );
  }
}
export default RepeatArray;

Click事件

ES5写法:

var React = require('react');
var MyComponent = React.createClass({
    handleClick: function() {
        React.findDOMNode(this.refs.myTextInput).focus();
    },
    render: function() {
        return (
            <div>
                <input type="text" ref="myTextInput" />
                <input type="button" value="Focus the text input" onClick= {this.handleClick} />
            </div>
        );
    }
});

module.exports = React.createClass({
    render: function() {
        return (
            <div>
                <MyComponent />
            </div>
        );
    }
});

ES6写法:

import React,{Component} from 'react';
class FocusText extends Component{
  handleClick(){
    React.findDOMNode(this.refs.myText).focus();
  }
  render(){
    return(
      <div>
        <input type="text" ref="myText" />
        <input type="button" value="focus the text input" onClick={this.handleClick.bind(this)} />
      </div>
    );
  }
}
class RepeatArray extends Component{
  constructor() {
    super();
  }
  render(){
    return (
      <div>
      <FocusText />
      </div>
    );
  }
}
export default RepeatArray;

State的用法,以toggel显示文字为例

ES5写法:

var React = require('react');
var LikeButton = React.createClass({
    getInitialState: function() {
        return {liked: false};
    },
    handleClick: function(e) {
        this.setState({liked: !this.state.liked});
    },
    render: function() {
        var text = this.state.liked ? 'like' : 'haven\'t liked';
        return (
            <p onClick = {this.handleClick}> 
                You {text} this.Click to toggle.
            </p>
        );
    }
});

module.exports = React.createClass({
    render: function() {
        return (<div><LikeButton /></div>);
    }
});

ES6写法:

import React,{Component} from 'react';
class StateUse extends Component{
  constructor(){
    super();
    this.state={
      like:true
    }
  }
  handleClick(){
    this.setState({like:!this.state.like});
  }
  render(){
    var text = this.state.like?'Like':"Unlike";
    return(
      <div>
        <p onClick={this.handleClick.bind(this)}>
        You {text} this.Click the toggle;
        </p>
      </div>
    );
  }
}
class RepeatArray extends Component{
  constructor() {
    super();
  }
  render(){
    return (
      <div>
      <StateUse />
      </div>
    );
  }
}
export default RepeatArray;

onChange事件,以及变量值的同步

ES5写法:

var React = require('react');
var InputComponent = React.createClass({
    getInitialState: function() {
        return {value: 'Hello!'};
    },
    handleChange: function(e) {
        this.setState({value: e.target.value})
    },
    render: function() {
        var value = this.state.value;
        return (
            <div>
                <input type="text" value={value} onChange={this.handleChangle} />
                <p>{value}</p>
            </div>
        );
    }
});
module.exports = React.createClass({
    render: function() {
        return (<div><InputComponent /></div>)
    }
});

ES6写法:

import React,{Component} from 'react';
class AsyncText extends Component{
  constructor(){
      super();
      this.state={
        value:'Hello!'
      }
  }
  handleChange(e){
    this.setState({value:e.target.value});
  }
  render(){
    var value= this.state.value;
    return(
      <div>
        <input type="text" value={value} onChange={this.handleChange.bind(this)} />
        <p>
          {value}
        </p>
      </div>
    );
  }
}
class RepeatArray extends Component{
  constructor() {
    super();
  }
  render(){
    return (
      <AsyncText />
      </div>
    );
  }
}
export default RepeatArray;

定时任务事件的嵌入

ES5写法:

var React = require('react');
var Hello = React.createClass({
    getInitState: function() {
        return {
            opacity: 1.0
        };
    },
    componentDidMount: function() {
        this.timer = setInterval (function() {
            var opacity = this.state.opacity;
            opacity -= .05;
            if (opacity < 0.1) {
                opacity = 1.0;
            }
            this.setState({
                opacity: opacity
            });
        }.bind(this), 100);
    },
    render: function() {
        return (
            <div style={{opacity: this.state.opacity}}>
                Hello {this.props.name}
            </div>
        );
    }
});

module.exports = React.createClass({
    render: function() {
        return (<div><Hello name="world" /></div>);
    }
});

ES6写法:

import React,{Component} from 'react';
class OpacityWord extends Component{
  constructor(){
    super();
    this.state={
      opacity:1.0
    }
  }
  componentWillMount(){
    let time  =  setInterval(()=>{
      let opacity = this.state.opacity;
      opacity -= 0.5;
      if (opacity<0.1) {
        opacity=1.0;
      }
      this.setState({opacity:opacity});
    }.bind(this),100);
  }
  render(){
    return (
      <div style={{ opacity:this.state.opacity }}>
        Hello, {this.props.name}!
      </div>
    );
  }

}

class RepeatArray extends Component{
  constructor() {
    super();
  }
  render(){
    return (
      <div>
       <OpacityWord />
      </div>
    );
  }
}
export default RepeatArray;

从服务端获取数据

ES5写法:

var React = require('react');
var UserGist = React.createClass({
    getInitState: function() {
        return {
            username: '',
            lastGistUrl: ''
        };
    },
    componentDidMount: function() {
        $.get(this.props.source, function(result) {
            var lastGist = result[0];
            this.setState({
                username: lastGist.owner.login,
                lastGistUrl: lastGist.html_url
            });
        }.bind(this));
    },
    render: function() {
        return (
            <div>
                {this.state.username}s last gist is <a href={this.state.lastGistUrl}> here </a>.
            </div>
        );
    }
});

module.exports = React.createClass({
    render: function() {
        return (
            <div>
                <UserGist source="https://api.github.com/users/octocat/gists" />
            </div>
        );
    }
});

ES6写法:

import React,{Component} from 'react';
class UserGist extends Component{
  constructor(){
    super();
    this.state={
      username:'',
      lastGistUrl:''
    }
  }
  componentWillMount(){
    $.get(this.props.source, function(result) {
      var lastGist = result[0];
      //if (this.isMounted()) {
        this.setState({
          username: lastGist.owner.login,
          lastGistUrl: lastGist.html_url
        });
      //}
    }.bind(this));
  }
  render(){
    return(
      <div>
        {this.state.username} ..
        <a href={this.state.lastGistUrl} >here</a>
      </div>
    );
  }
}
class RepeatArray extends Component{
  constructor() {
    super();
  }
  render(){
    return (
      <div>
      <UserGist source="https://api.github.com/users/octocat/gists" />
      </div>
    );
  }
}
export default RepeatArray;

React Native实战

写一个简单的页面,支持输入关键字然后以列表形式呈现github里搜索出来的结果。效果如下:




ES5写法:

'use strict';
var React = require('react-native');
var {
    Image,
    ListView,
    TextInput,
    AppRegistry,
    Component,
    StyleSheet,
    Text,
    View,
} = React;

var BASE_URL = "https://api.github.com/search/repositories?q=";

var customView = React.createClass({

    getInitialState: function() {
        return {
            dataSource: new ListView.DataSource({
                rowHasChanged: (row1, row2) => row1 !== row2,
            }),
        };
    },

    render: function() {
        if (this.state.dataSource.getRowCount() === 0) {
            console.log('YES');
        }
        var content = this.state.dataSource.getRowCount() === 0 ?
        <Text style={styles.blankText}>
            Please enter a search term to see results.
        </Text> :
        <ListView
            ref="listview"
            dataSource={this.state.dataSource}
            renderRow={this.renderRow}
            automaticallyAdjustContentInsets={false}
            keyboardDismissMode="onDrag"
            keyboardShouldPersistTaps={true}
            showsVerticalScrollIndicator={false} />;

        return (
            <View style={styles.container}>
                <TextInput
                    autoCapitalize="none"
                    autoCorrect={false}
                    placeholder="Search for a project..."
                    style={styles.searchBarInput} onEndEditing={this.onSearchChange}/>
                {content}
            </View>
        );
    },

    onSearchChange: function(event: Object) {
        var searchTerm = event.nativeEvent.text.toLowerCase();
        var queryURL = BASE_URL + encodeURIComponent(searchTerm);

        fetch(queryURL)
            .then((response) => response.json())
            .then((responseData) => {
                if (responseData.items) {
                    this.setState({
                        dataSource: this.state.dataSource.cloneWithRows(responseData.items),
                    });
                }
            }).done();
    },

    renderRow: function(repo: Object) {
        return (
            <View>
                <View style={styles.row}>
                    <Image source={{uri: repo.owner.avatar_url}}
                    style={styles.profPic}/>
                    <View style={styles.textContainer}>
                        <Text style={styles.title}>
                            {repo.name}
                        </Text>
                        <Text style={styles.subTitle}>
                            {repo.owner.login}
                        </Text>
                    </View>
                    <View style={styles.cellBorder}></View>
                </View>
            </View>
        );
    },
});

var styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#ffffff',
    },
    searchBarInput: {
        marginTop: 30,
        padding: 5,
        fontSize: 15,
        height: 30,
        backgroundColor: '#EAEAEA',
    },
    row: {
        alignItems: 'center',
        backgroundColor: 'white',
        flexDirection: 'row',
        padding: 5,
    },
    cellBorder: {
        backgroundColor: 'rgba(0,0,0,0.1)',
        height: 1,
        marginLeft: 4,
    },
    profPic: {
        width: 50,
        height: 50,
    },
    title: {
        fontSize: 20,
        marginBottom: 8,
        fontWeight: 'bold',
    },
    subTitle: {
        fontSize: 16,
        marginBottom: 8,
    },
    textContainer: {
        paddingLeft: 10,
    },
    blankText: {
        padding: 10,
        fontSize: 20,
    }
});

AppRegistry.registerComponent('customView', () => customView);

ES6写法:

import React, {
    Image,
    ListView,
    TextInput,
    AppRegistry,
    Component,
    StyleSheet,
    Text,
    View,
}
from 'react-native';
const BASE_URL = "https://api.github.com/search/repositories?q=";

class customView extends Component {

    constructor() {
        super();
    }

    state = {
        dataSource: new ListView.DataSource({
            rowHasChanged: (row1, row2) => row1 !== row2,
        }),
    }

    render() {
        if (this.state.dataSource.getRowCount() === 0) {
            console.log('YES');
        }
        var content = this.state.dataSource.getRowCount() === 0 ?
        <Text style={styles.blankText}>
            Please enter a search term to see results.
        </Text> :
        <ListView
            ref="listview"
            dataSource={this.state.dataSource}
            renderRow={this.renderRow}
            automaticallyAdjustContentInsets={false}
            keyboardDismissMode="onDrag"
            keyboardShouldPersistTaps={true}
            showsVerticalScrollIndicator={false} />;

        return (
            <View style={styles.container}>
                <TextInput
                    autoCapitalize="none"
                    autoCorrect={false}
                    placeholder="Search for a project..."
                    style={styles.searchBarInput} onEndEditing={this.onSearchChange}/>
                {content}
            </View>
        );
    }

    onSearchChange(event: Object) {
        var searchTerm = event.nativeEvent.text.toLowerCase();
        var queryURL = BASE_URL + encodeURIComponent(searchTerm);

        fetch(queryURL)
            .then((response) => response.json())
            .then((responseData) => {
                if (responseData.items) {
                    this.setState({
                        dataSource: this.state.dataSource.cloneWithRows(responseData.items),
                    });
                }
            }).done();
    }

    renderRow(repo: Object) {
        return (
            <View>
                <View style={styles.row}>
                    <Image source={{uri: repo.owner.avatar_url}}
                    style={styles.profPic}/>
                    <View style={styles.textContainer}>
                        <Text style={styles.title}>
                            {repo.name}
                        </Text>
                        <Text style={styles.subTitle}>
                            {repo.owner.login}
                        </Text>
                    </View>
                    <View style={styles.cellBorder}></View>
                </View>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#ffffff',
    },
    searchBarInput: {
        marginTop: 30,
        padding: 5,
        fontSize: 15,
        height: 30,
        backgroundColor: '#EAEAEA',
    },
    row: {
        alignItems: 'center',
        backgroundColor: 'white',
        flexDirection: 'row',
        padding: 5,
    },
    cellBorder: {
        backgroundColor: 'rgba(0,0,0,0.1)',
        height: 1,
        marginLeft: 4,
    },
    profPic: {
        width: 50,
        height: 50,
    },
    title: {
        fontSize: 20,
        marginBottom: 8,
        fontWeight: 'bold',
    },
    subTitle: {
        fontSize: 16,
        marginBottom: 8,
    },
    textContainer: {
        paddingLeft: 10,
    },
    blankText: {
        padding: 10,
        fontSize: 20,
    }
});

AppRegistry.registerComponent('customView', () => customView);

参考 ReactJS结合ES6入门Template

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值