1. 程式人生 > >React Native 屬性.樣式.狀態

React Native 屬性.樣式.狀態

一. HelloWord

1.初始化工程

react-native init Hello
cd Hello
react-native run-ios

這個有一點要注意,博主是在終端直接操作的,後來把檔案移動到專門的React Native資料夾裡,移動之後,之前建立的專案都執行不起來了,會出以下問題

 We couldn't boot your defined simulator due to an already booted simulator. We are limited to one simulator launched at a time.
 開始我以為系統那裡有問題把寫的專案都刪了,移動回去之後又好了,以後再建立專案時,直接在對應資料夾中建立了(怎麼在移動後仍然可以用,以後有時間在研究)
 

2.HelloWord

//引入React, 引入react中Component這一模組
import React, { Component } from 'react';
import {
    AppRegistry, //註冊
    StyleSheet,  //樣式
    Text,        //文字
    View         //檢視
} from 'react-native';

//這是ES6的一種寫法 建立了一個Hello的類繼承Component
class Hello extends Component {
    // 初始化方法 --->相當於OC中的ViewDidLoad --->返回具體的元件內容
    //寫結構和內容
    render() {
        //返回
        return (
            <Text>Hello world!</Text>
        );
    }
}
//export default關鍵字。它的意思是匯出(export)當前元件,以允許其他元件引入(import)和使用當前元件
export default class FetchAPI extends Component {
}
/*  注意:
 1. 這裡用引號括起來的'Hello'必須和你init建立的專案名一致
 2. AppRegistry模組則是用來告知React Native哪一個元件被註冊為整個應用的根容器。一般在整個應用裡AppRegistry.registerComponent這個方法只會呼叫一次。
 */
AppRegistry.registerComponent('Hello', () => Hello);

ReactNative中所有的變數都用{}來寫

上面的示例程式碼中的import、from、class、extends、以及() =>箭頭函式等新語法都是ES2015中的特性。如果你不熟悉ES2015的話,可以看阮一峰老師的書(http://es6.ruanyifeng.com),還有論壇的這篇總結

示例中的這一行<Text>Hello world!</Text>叫做JSX——是一種在JavaScript中嵌入XML結構的語法。React設計的JSX語法卻是讓你在程式碼中嵌入結構標記。這裡我們使用的是React Native的元件。上面的示例程式碼中,使用的是內建的<Text>元件,它專門用來顯示文字。


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

二. Props(屬性)
大多陣列件在建立時就可以使用各種引數來進行定製。用於定製的這些引數就稱為props(屬性)。
我們使用兩種資料來控制一個元件:props和state。props是在父元件中指定,而且一經指定,在被指定的元件的生命週期中則不再改變。 對於需要改變的資料用state。

以常見的基礎元件Image為例,在建立一個圖片時,傳入兩個prop。
1) source: 指定要顯示的圖片的地址;  
2) style: 來控制其尺寸。
import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View,Image
} from 'react-native';

class Hello extends Component {
    render() {
        let pic = {
            uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
        };
        return (
            <Image source={pic} style={{width: 200, height: 120}} />
        );
    }
}
AppRegistry.registerComponent('Hello', () => Hello);
譯註:在iOS上使用http連結的圖片地址可能不會顯示,[參見這篇說明修改](https://segmentfault.com/a/1190000002933776)。

請注意{pic}外圍有一層括號,我們需要用括號來把pic這個變數嵌入到JSX語句中。括號的意思是括號內部為一個js變數或表示式,需要執行後取值。因此我們可以把任意合法的JavaScript表示式通過括號嵌入到JSX語句中。

自定義的元件也可以使用props。通過在不同的場景使用不同的屬性定製,可以儘量提高自定義元件的複用範疇。只需在render函式中引用this.props,然後按需處理即可。下面是一個例子:

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View, 
} from 'react-native';


class Greeting extends Component {
    render() {
        return (
            <Text>Hello {this.props.name}!</Text>
        );
    }
}

class Hello extends Component {
    render() {
        return (
            <View style={{alignItems: 'center'}}>
            //在Greeting元件中將name作為一個屬性來定製,這樣可以複用這一元件來製作各種不同的“問候語”。
              <Greeting name='歡迎來到' />
              <Greeting name='React native' />
              <Greeting name='學習中' />
            </View>
        );
    }
}
AppRegistry.registerComponent('Hello', () => Hello);

上面的例子把Greeting元件寫在JSX語句中,用法和內建元件並無二致。
View - 元件。View 常用作其他元件的容器,來幫助控制佈局和樣式。
僅僅使用props和基礎的Text、Image以及View元件,你就已經足以編寫各式各樣的UI元件了。


三. State(狀態)

一般來說,你需要在constructor中初始化state(ES6),然後在需要修改時呼叫setState方法。
假如我們需要製作一段不停閃爍的文字。文字內容本身在元件建立時就已經指定好了,所以文字內容應該是一個prop。而文字的顯示或隱藏的狀態(快速的顯隱切換就產生了閃爍的效果)則是隨著時間變化的,因此這一狀態應該寫到state中。
import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View, Image
} from 'react-native';

class HelloApp extends Component {
    constructor(props) {
        super(props);
        this.state = { showText: true };
        // 每1000毫秒對showText狀態做一次取反操作
        setInterval(() => {
            this.setState({ showText: !this.state.showText });
        }, 1000);
    }
    render() {
        // 根據當前showText的值決定是否顯示text內容
        let display = this.state.showText ? this.props.text : ' ';
        return (
            <Text>{display}</Text>
        );
    }
}
class Hello extends Component {
    render() {
        return (
            <View>
              <HelloApp text='I love to blink' />
              <HelloApp text='Yes blinking is so great' />
              <HelloApp text='Why did they ever take this out of HTML' />
              <HelloApp text='Look at me look at me look at me' />
            </View>
        );
    }
}
AppRegistry.registerComponent('Hello', () => Hello);

實際開發中,我們一般不會在定時器函式(setInterval、setTimeout等)中來操作state。典型的場景是在接收到伺服器返回的新資料,或者在使用者輸入資料之後。你也可以使用一些“狀態容器”比如Redux來統一管理資料流(譯註:但我們不建議新手過早去學習redux)。
State的工作原理和React.js完全一致,所以對於處理state的一些更深入的細節,你可以參閱[React.Component API](http://example.com/)。

四 .Style(樣式)
所有的核心元件都接受名為style的屬性。這些樣式名基本上是遵循了web上的CSS的命名,只是按照JS的語法要求使用了駝峰命名法,例如將background-color改為backgroundColor。

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

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

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View
} from 'react-native';

export default class StyleAndProps extends Component {
  render() {
    return (
      <View style={styles.container}>
          {/*<Text style={[styles.title,{fontStyle:'italic' }]}>*/}
          {/*<Text style={styles.title}>
          Welcome to React <Text style={{fontWeight:'600'}}>Native!</Text>
        </Text>*/}
       <HeaderText>
         Welcome to React
       </HeaderText>

      </View>
    );
  }
}
//在主檔案上建立一個顯示文字的元件(自定義元件)
class HeaderText extends Component {
    render() {
        return (
            <Text style={styles.title}>
                {/*在這個元件中顯示的文字就是: this.props.children */}
                {this.props.children}
              </Text>

        );
    }
}
const styles = StyleSheet.create({
  //常用樣式
  container: {
    flex: 1,
    // justifyContent: 'center',
    // alignItems: 'center',
    backgroundColor: '#F5FCFF',
    marginBottom:20,

    margin :30,
    borderColor:'#6435c9',
    borderWidth:1,
    shadowColor:'#6435c9',
    shadowOpacity:0.6, //陰影不透明度
    shadowRadius:2, //陰影半徑
    shadowOffset: {
        height:1,
        width:0
      },
    marginLeft: 20,
    marginRight: 20,
   // marginTop:40
      paddingTop:130
  },
// 文字樣式
    title:{
    fontSize:20,
    color:'#6435c9'   ,
    textAlign:'center', //文字對齊方式
    fontStyle:'italic' ,//字型樣式
    letterSpacing:2 ,//字間距
    lineHeight:33,   //行間距
    fontFamily:'Helvetica Neue',
    fontWeight:'300', //文字的粗細,粗體,細體或者300等
    textDecorationLine:'underline',//設定下劃線或者刪除線(line-through)
    textDecorationStyle:'dashed' //線的樣式:實線(solid),雙實線(double),點線(dotted),虛線(dashed)
    }
});

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