React Native基礎之props,state,style

渣渣008發表於2017-12-13

本人是搞安卓的,所以。。。

基礎

搭建開發環境就不說啦。

建立專案

搭建好開發環境之後,找個目錄,建立專案,然後執行專案,建立出來的專案的gradle的版本如果本地沒有的話,建議改成本地有的,不然要下載好久。

react-native init 專案名
cd 專案目錄
react-native run-android
複製程式碼

*提示:*你可以使用--version引數建立指定版本的專案。 例如react-native init MyApp --version 0.39.2。注意版本號必須精確到兩個小數點。

還有一點,RN的選單需要按選單鍵才能出來,但是現在很多手機都沒有選單鍵啦,RN肯定早就考慮到啦這一點,搖一搖手機就出來啦。

Hello World
import React, { Component } from 'react';
import { AppRegistry, Text } from 'react-native';

class HelloWorldApp extends Component {
  render() {
    return (
      <Text>Hello world!</Text>
    );
  }
}
// 注意,這裡用引號括起來的'HelloWorldApp'必須和你init建立的專案名一致
AppRegistry.registerComponent('HelloWorldApp', () => HelloWorldApp);
複製程式碼

RN的Hello World程式如上面所示的。 上面的示例程式碼中的import、from、class、extends、以及() =>箭頭函式等新語法都是ES2015(也叫作ES6)中的特性。如果你不熟悉ES2015的話,可以看看阮一峰老師的書,還有論壇的這篇總結。 *提示:*順便說一句,阮一峰老師的部落格寫的真的很好,很多東西都講的非常透徹。

上面的程式碼定義了一個名為HelloWorldApp的新的元件(Component),並且使用了名為AppRegistry的內建模組進行了“註冊”操作。你在編寫React Native應用時,肯定會寫出很多新的元件。而一個App的最終介面,其實也就是各式各樣的元件的組合。元件本身結構可以非常簡單——唯一必須的就是在render方法中返回一些用於渲染結構的JSX語句。

AppRegistry模組則是用來告知React Native哪一個元件被註冊為整個應用的根容器。你無需在此深究,因為一般在整個應用裡AppRegistry.registerComponent這個方法只會呼叫一次。上面的程式碼裡已經包含了具體的用法,你只需整個複製到index.ios.js或是index.android.js檔案中即可執行。 *提示:*上面的話出自編寫Hello World

props

大多陣列件在建立時就可以使用各種引數來進行定製。用於定製的這些引數就稱為props(屬性)。所謂props,就是屬性傳遞,而且是單向傳遞的。屬性多的時候,可以傳遞一個物件,這是es6中的語法。

圖片文字元件
例如,我現在要定製一個這樣的元件,上面顯示圖片,下面顯示文字,當然知道官方的元件Image,Text已經足已完成這樣的功能,我們現在為了展示props的用途這裡來學習一下。 編寫的程式碼大概是這樣,當然其實也是利用官方的元件做的啦。

class DescText extends Component {
    render() {
        return (
            <Text>Desc: {this.props.txt}!</Text>
        );
    }
}

class BannerImg extends Component {
    render() {
        return (
            <Image source={this.props.img} style={{width: 300, height: 200}}/>
        );
    }
}

class BannerSample extends Component {
    render() {
        let va = {
            text: 'qingyong',
            uri: 'http://pic62.nipic.com/file/20150319/12632424_132215178296_2.jpg'
        };
        return (
            <View style={{alignItems: 'center'}}>
                <BannerImg img={va}/>
                <DescText txt={va.text}/>
            </View>
        );
    }
}
複製程式碼

我們定製啦兩個元件DescText,BannerImg分別來展示文字和圖片,這裡在兩個元件裡面分別定義了兩個屬性txt,img,然後在BannerSample裡面去使用了這兩個元件以及我們定義好的屬性。屬性是不是很簡單:定義,然後使用即可

其實按我的理解:

屬性最好的用途是封裝,我們可以通過把一些基礎元件封裝成一個Component,然後寫好自定義的屬性,封裝成自己的基礎元件,這樣就算以後RN的api改變了,也不影響我們的使用,我們只需要修改元件即可,不用大肆修改專案。

比如上面的圖片中的展示,我們雖然可以使用上面的方式制定兩個元件,分別引用,或者直接使用RN的基礎元件,不用封裝,但是呢,如果比較多的地方都需要這種展示,我們就可以封裝成一個上面顯示圖片,下面顯示文字的元件。 示例如下:只是在剛才的基礎上程式碼合併了一下而已。

class Banner extends Component {
    render() {
        return (
            <View style={{alignItems: 'center'}}>
                <Image source={this.props.img} style={{width: 300, height: 200}}/>
                <Text>Desc: {this.props.txt}!</Text>
            </View>
        );
    }
}

class BannerSample extends Component {
    render() {
        let va = {
            text: 'qingyong',
            uri: 'http://pic62.nipic.com/file/20150319/12632424_132215178296_2.jpg'
        };
        return (
            <View>
                <Banner img={va} txt={va.text}/>
            </View>
        );
    }
}
複製程式碼

是不是感受到了封裝的好處啦。

State

React靠一個state來維護狀態,當state發生變化則更新DOM。控制一個元件,一般有兩種資料型別,一種是props,一種是stateprops是在父元件中設定,一旦指定,它的生命週期是不可以改變的。對於元件中資料的變化,我們是通過state來控制的。 一般來說,你需要在constructor中初始化state(譯註:這是ES6的寫法,早期的很多ES5的例子使用的是getInitialState方法來初始化state,這一做法會逐漸被淘汰),然後在需要修改時呼叫setState方法。 這裡還是展示官方的示例吧,但是其實我感覺官方的這個示例並不是特別好,沒有把state的功能完全展示出來。

class HiddenText extends Component {
    constructor(props) {
        super(props);
        this.state = {
            showTxt: true
        };
        setInterval(
            () => {
                this.setState({showTxt: !this.state.showTxt});
            }
            , 1000);
    }

    render() {
        let display = this.state.showTxt ? this.props.text : '';
        return (
            <Text>{display}</Text>
        );
    }
}

class HiddenSample extends Component {
    render() {
        return (
            <View style={{alignItems: 'center'}}>
                <HiddenText text='one'/>
                <HiddenText text='two'/>
                <HiddenText text='three'/>
            </View>
        )
    };
}
複製程式碼

首先,它是自定義了一個HiddenText的元件,在建構函式中初始化了state,然後寫了一個定時器,每個1秒改變一次狀態,然後setState,然後在渲染render()方法中,判斷狀態的變化,如果是true,顯示文字,false顯示空。這樣一閃一閃的效果就出來了。

官方的這個示例也是簡單的介紹了state怎麼使用的,並不是特別詳細的。比如在外面怎麼主動呼叫setState的。

Style

在React Native中我們不需要使用什麼特殊的語言或者語法去定義樣式,我們還是使用JavaScript來寫樣式。所有的核心元件都接受名為style的屬性。唯一的不同就是屬性樣式的命名使用了駝峰命名法,例如將background-color改為backgroundColor

感覺這個對我這個css樣式不熟悉的人來說,還是比較蛋疼的。

style屬性可以是一個普通的JavaScript物件。這是最簡單的用法,因而在示例程式碼中很常見。你還可以傳入一個陣列——在陣列中位置居後的樣式物件比居前的優先順序更高,這樣你可以間接實現樣式的繼承。

實際開發中元件的樣式會越來越複雜,我們建議使用StyleSheet.create來集中定義元件的樣式。

class LotsOfStyles extends Component {
    render() {
        return (
            <View>
                <Text style={styles.red}>just red</Text>
                <Text style={styles.bigblue}>just bigblue</Text>
                <Text style={[styles.bigblue, styles.red]}>bigblue, then red</Text>
                <Text style={[styles.red, styles.bigblue]}>red, then bigblue</Text>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    bigblue: {
        color: 'blue',
        fontWeight: 'bold',
        fontSize: 30,
    },
    red: {
        color: 'red',
    },
});
複製程式碼

效果.png
可以很明顯的看到後面的style會覆蓋前面的。 做專案寫程式碼的時候,還是要多看文件,熟悉了就會比較快啦。

相關文章