1. 程式人生 > >ReactJS入門ES6寫法

ReactJS入門ES6寫法

HTML 模板
使用 React 的網頁原始碼,結構大致如下。

<!DOCTYPE html>
<html>
  <head>
    <script src="../build/react.js"></script>
    <script src="../build/react-dom.js"></script>
    <script src="../build/browser.min.js"></script>
  </head>
  <body>
    <div
id="example">
</div> <script type="text/babel"> // ** Our code goes here! ** </script> </body> </html>

1.輸出”Hello“

//ES5
 ReactDOM.render(
   <h1>Hello, world!</h1>,
   document.getElementById('example')
 );

//ES6
 class HelloMessage extends React
.Component{
render(){ return <h1>Hello {this.props.name}</h1>; } } class Output extends React.Component{ render(){ return ( <div> <HelloMessage name="John" /> </div> ); } } ReactDOM.render(<Output />,document.getElementById('example'
));

2.陣列遍歷

 //ES5
 var names = ['Alice', 'Emily', 'Kate'];
 ReactDOM.render(
    <div>
    {
      names.map(function (name) {
        return <div>Hello, {name}!</div>
      })
    }
    </div>,
    document.getElementById('example')
  );

//ES6
class Greeting extends React.Component {      
   render() {
     const names = ['Alice', 'Emily', 'Kate'];
     return (
       <div>
       {
         names.map((name,index) => <div key = {index}>Hello, {name}!</div>)
       }
       </div>
     );
   }
 }
 ReactDOM.render(<Greeting />,document.getElementById('example'));

3.this.props.children
元件類的 this.props屬性,可以在組建物件上獲取,
this.props 物件的屬性與元件的屬性一一對應,但是有一個例外,就是 this.props.children 屬性。它表示元件的所有子節點

//ES5
var NotesList = React.createClass({
  render: function() {
    return (
      <ol>
      {
        React.Children.map(this.props.children, function (child) {
          return <li>{child}</li>;
        })
      }
      </ol>
    );
  }
});

//ES6
class NotesList extends React.Component {      
  render() {
    return (
      <ol>
        {
          React.Children.map(this.props.children, (child) => {return <li>{child}</li>})
        }
      </ol>
    )
  }
}

ReactDOM.render(
  <NotesList>
    <span>hello</span>
    <span>world</span>
  </NotesList>,
  document.body
);

4.PropTypes和defaultProps
定義元件的屬性型別和預設屬性,統一使用static成員來實現

//ES5
var Video = React.createClass({
    getDefaultProps: function() {
        return {
            autoPlay: false,
            maxLoops: 10,
        };
    },
    propTypes: {
        autoPlay: React.PropTypes.bool.isRequired,
        maxLoops: React.PropTypes.number.isRequired,
        posterFrameSrc: React.PropTypes.string.isRequired,
        videoSrc: React.PropTypes.string.isRequired,
    },
    render: function() {
        return (
            <View />
        );
    },
});
//ES6
class Video extends React.Component {
    static defaultProps = {
        autoPlay: false,
        maxLoops: 10,
    };  // 注意這裡有分號
    static propTypes = {
        autoPlay: React.PropTypes.bool.isRequired,
        maxLoops: React.PropTypes.number.isRequired,
        posterFrameSrc: React.PropTypes.string.isRequired,
        videoSrc: React.PropTypes.string.isRequired,
    };  // 注意這裡有分號
    render() {
        return (
            <View />
        );
    } // 注意這裡既沒有分號也沒有逗號
}

5.ref屬性
從元件獲取真實 DOM節點

//ES5
var MyComponent = React.createClass({
  handleClick: function() {
    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>
    );
  }
});

//ES6
class MyComponent extends React.Component {
  constructor(props){
    super(props);
    this.handleClick = this.handleClick.bind(this)
  }
  handleClick(){
    this.refs.myTextInput.focus()
  }
  render(){
    return(
      <div>
        <input type="text" ref="myTextInput" />
        <input type="button" value="Focus the text input" onClick={this.handleClick} />
      </div>
    )
  }
}

ReactDOM.render(
  <MyComponent />,
  document.getElementById('example')
);

6.元件狀態機 this.state
將元件看成是一個狀態機,一開始有一個初始狀態,然後使用者互動,導致狀態變化,從而觸發重新渲染 UI

//ES5
var LikeButton = React.createClass({
  getInitialState: function() {
    return {
      liked: false,
      value: 'crlin'
    };
  },
  handleClick: function(event) {
    this.setState({liked: !this.state.liked});
  },
  handleChange: function(event) {
    this.setState({value: event.target.value});
  },
  render: function() {
    var text = this.state.liked ? 'like' : 'haven\'t liked',
        value = this.state.value;
    return (
      <div> 
        <p onClick={this.handleClick}>You {text} this. Click to toggle.</p>
        <input type="text" value={value} onChange={this.handleChange} />
        <p>{value}</p>
      </div>
    );
  }
});

//ES6
class LikeButton extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      liked: false,
      value: "crlin"
    }
  }
  handleClick(){
    this.setState({
      liked: !this.state.liked
    })
  }
  handleChange(event){
    this.setState({
      value: event.target.value
    })
  }
  render(){
    let text = this.state.liked ? 'like' : 'haven\'t liked',
        value = this.state.value;
    return (   
      <div> 
        <p onClick={this.handleClick.bind(this)}>You {text} this. Click to toggle.</p>
        <input type="text" value={value} onChange={this.handleChange.bind(this)} />
        <p>{value}</p>
      </div>
    );
  }
}
ReactDOM.render(
  <LikeButton />,
  document.getElementById('example')
);
//ES5
var Hello = React.createClass({
  getInitialState: 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>
    );
  }
});

//ES6
class Hello extends React.Component{
  constructor(props) {
    super(props);
    this.state = {
      opacity: 1.0
    }
  }

  componentDidMount() {
    let timer = setInterval( () => {
      let opacity = this.state.opacity;
      opacity -= .05;
      if (opacity < 0.1) {
        opacity = 1.0;
      }
      this.setState({
        opacity: opacity
      });
    }, 100);
  }

  render() {
    return (
      <div style={{opacity: this.state.opacity}}>
        Hello {this.props.name}
      </div>
    );
  }
};
ReactDOM.render(
  <Hello name="world"/>,
  document.getElementById('example')
);

8.ajax請求

可以使用 componentDidMount 方法設定 Ajax 請求,等到請求成功,再用 this.setState 方法重新渲染 UI

//ES5
var UserGist = React.createClass({
  getInitialState: function() {
    return {
      username: '',
      lastGistUrl: ''
    };
  },

  componentDidMount: function() {
    $.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: function() {
    return (
      <div>
        {this.state.username}'s last gist is
        <a href={this.state.lastGistUrl}>here</a>.
      </div>
    );
  }
});

ReactDOM.render(
  <UserGist source="https://api.github.com/users/octocat/gists" />,
  document.body
);

//ES6
class UserGist extends React.Component{
  constructor(props){
    super(props);
    this.state = {
      username:'',
      lastGistUrl:''
    }
  }
  componentDidMount(){
    $.get(this.props.source, (result) => {
      let lastGist = result[0];    
        this.setState({
          username: lastGist.owner.login,
          lastGistUrl: lastGist.html_url
        });
    });
  }
  render(){
    return(
      <div>
        {this.state.username} ..
        <a href={this.state.lastGistUrl} >here</a>
      </div>
    );
  }
}
class RepeatArray extends React.Component{
  constructor(props) {
    super(props);
  }
  render(){
    return (
      <div>
      <UserGist source="https://api.github.com/users/octocat/gists" />
      </div>
    );
  }
}
ReactDOM.render(
  <RepeatArray/>,
  document.getElementById('example')
);