1. 程式人生 > >React-native 基本語法一

React-native 基本語法一

1.引用

import React, { 
    Component,
    PropTypes,
} from 'react';
import {
    Image,
    Text
} from 'react-native'

2.匯出單個類

匯出一個類給別的模組用

export default class MyComponent extends Component{
    ...
}

引用時

import MyComponent from './MyComponent';

3.定義元件

通過定義一個繼承自React.Component的class來定義一個元件類

class Photo extends React.Component {
    render() {
        return (
            <Image source={this.props.source} />
        );
    }
}

給元件定義方法

class Photo extends React.Component {
    componentWillMount() {

    }
    render() {
        return (
            <Image source={this.props.source} />
        );
    }
}

4.定義元件的屬性型別和預設屬性

統一使用static成員來實現

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.初始化STATE

class Video extends React.Component {
    state = {
        loopsRemaining: this.props.maxLoops,
    }
}
或者

class Video extends React.Component {
    constructor(props){
        super(props);
        this.state = {
            loopsRemaining: this.props.maxLoops,
        };
    }
}

6.把方法作為回撥提供

通過bind來繫結this引用,或者使用箭頭函式(它會綁定當前scope的this引用)來呼叫

class PostInfo extends React.Component
{
    handleOptionsButtonClick(e){
        this.setState({showOptionsModal: true});
    }
    render(){
        return (
            <TouchableHighlight 
                onPress={this.handleOptionsButtonClick.bind(this)}
                onPress={e=>this.handleOptionsButtonClick(e)}
                >
                <Text>{this.props.label}</Text>
            </TouchableHighlight>
        )
    },
}

箭頭函式實際上是在這裡定義了一個臨時的函式,箭頭函式的箭頭 =>之前是一個空括號、單個的引數名、或用括號括起的多個引數名,而箭頭之後可以是一個表示式(作為函式的返回值),或者是用花括號括起的函式體(需要自行通過return來返回值,否則返回的是undefined)。

// 箭頭函式的例子
()=>1
v=>v+1
(a,b)=>a+b
()=>{
    alert("foo");
}
e=>{
    if (e == 0){
        return 0;
    }
    return 1000/e;
}

需要注意的是,不論是bind還是箭頭函式,每次被執行都返回的是一個新的函式引用,因此如果你還需要函式的引用去做一些別的事情(譬如解除安裝監聽器),那麼你必須自己儲存這個引用

// 錯誤的做法
class PauseMenu extends React.Component{
    componentWillMount(){
        AppStateIOS.addEventListener('change', this.onAppPaused.bind(this));
    }
    componentDidUnmount(){
        AppStateIOS.removeEventListener('change', this.onAppPaused.bind(this));
    }
    onAppPaused(event){
    }
}

// 正確的做法
class PauseMenu extends React.Component{
    constructor(props){
        super(props);
        this._onAppPaused = this.onAppPaused.bind(this);
    }
    componentWillMount(){
        AppStateIOS.addEventListener('change', this._onAppPaused);
    }
    componentDidUnmount(){
        AppStateIOS.removeEventListener('change', this._onAppPaused);
    }
    onAppPaused(event){
    }
}

這個帖子中我們還學習到一種新的做法:

// 正確的做法
class PauseMenu extends React.Component{
    componentWillMount(){
        AppStateIOS.addEventListener('change', this.onAppPaused);
    }
    componentDidUnmount(){
        AppStateIOS.removeEventListener('change', this.onAppPaused);
    }
    onAppPaused = (event) => {
        //把方法直接作為一個arrow function的屬性來定義,初始化的時候就繫結好了this指標
    }
}

7.Mixins 代替的實現方式

//Enhance.js
import { Component } from "React";

export var Enhance = ComposedComponent => class extends Component {
    constructor() {
        this.state = { data: null };
    }
    componentDidMount() {
        this.setState({ data: 'Hello' });
    }
    render() {
        return <ComposedComponent {...this.props} data={this.state.data} />;
    }
};

//HigherOrderComponent.js
import { Enhance } from "./Enhance";

class MyComponent {
    render() {
        if (!this.data) return <div>Waiting...</div>;
        return <div>{this.data}</div>;
    }
}

export default Enhance(MyComponent); // Enhanced component


用一個“增強函式”,來某個類增加一些方法,並且返回一個新類,這無疑能實現mixin所實現的大部分需求。


8.解構&屬性延展

結合使用ES6+的解構和屬性延展,我們給孩子傳遞一批屬性更為方便了。這個例子把className以外的所有屬性傳遞給div標籤:

class AutoloadingPostsGrid extends React.Component {
    render() {
        var {
            className,
            ...others,  // contains all properties of this.props except for className
        } = this.props;
        return (
            <div className={className}>
                <PostsGrid {...others} />
                <button onClick={this.handleLoadMoreClick}>Load more</button>
            </div>
        );
    }
}

下面這種寫法,則是傳遞所有屬性的同時,用覆蓋新的className值:

<div {...this.props} className="override">
    …
</div>

這個例子則相反,如果屬性中沒有包含className,則提供預設的值,而如果屬性中已經包含了,則使用屬性中的值

<div className="base" {...this.props}>
    …
</div>

文章來自 http://bbs.reactnative.cn/topic/15/react-react-native-%E7%9A%84es5-es6%E5%86%99%E6%B3%95%E5%AF%B9%E7%85%A7%E8%A1%A8/2 的總結