React Native基礎入門

1.React Native組件

獨立的、可重用的模塊。
有3種方式可以創建組件:1. ES6方式創建;2. ES5方式創建;3.函數式定義無狀態組件方式

// ES6方式創建組件
type Props = {};
export default class App extends Component<Props> {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>Welcome to React Native!</Text>
        <Text style={styles.instructions}>To get started, edit App.js</Text>
        <Text style={styles.instructions}>{instructions}</Text>
      </View>
    );
  }
}

// ES5方式創建組件
var App = React.createClass({
  render(){
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>Welcome to React Native!</Text>
        <Text style={styles.instructions}>To get started, edit App.js</Text>
        <Text style={styles.instructions}>{instructions}</Text>
      </View>
    );
  }
})
module.exports = App;

// 無狀態組件方式:沒有this,沒有生命周期函數
function App(){
  return (
    <View style={styles.container}>
      <Text style={styles.welcome}>Welcome to React Native!</Text>
      <Text style={styles.instructions}>To get started, edit App.js</Text>
      <Text style={styles.instructions}>{instructions}</Text>
    </View>
  );
}
module.exports = App;

2.React Native組件生命周期

React Native使用React語法,與React組件擁有一樣的生命周期函數,

分為3種狀態:
Mounting:掛載,已插入真實Dom
Updating:更新,正在被重新渲染
Unmounting:卸載,已移出真實Dom
4個階段
創建:只調用getDefaultProps方法
實例化getInitialState,componentWillMount,render(渲染并返回一個虛擬Dom),componentDidMount(根據虛擬Dom對象創建真實Dom,可以在此獲取Dom節點)
更新static getDerivedStateFromProps(props, state);shouldComponentUpdate(nextProps, nextState)render()getSnapshotBeforeUpdate(props, state);componentDidUpdate(preProps, preState, snapshot)
銷毀componentWillUnmount

3.組件的導入與導出

// ES6:export導出,import導入
// 導出
export default class App extends Component{
  render() {
    return (
      <Text style={styles.welcome}>Welcome to React Native!</Text>
    );
  }
}
// 導入
import App from './App';

// ES5: module.export導出,import導入
// 導出
var App = React.createClass({
  render(){
    return (
      <Text style={styles.welcome}>Welcome to React Native!</Text>
    );
  }
})
module.exports = App;
//導入
import App from './App';

4.props

React相當于MVC的View層,負責展示,并不涉及到數據,但是組件在使用的過程中有兩個屬性是和數據有關的:props和state

props:組件自身的屬性,一般用于嵌套的內外層組件中,由父組件傳給子組件,負責傳遞信息,也可以用于屬性約束和驗證。(props對象中的屬性與組件屬性一一對應--除this.props.children之外,不要直接修改props屬性中的值)
...this.props:可以將父組件中傳遞的全部屬性復制給子組件
this.props.children:組件的所有子節點。它的返回值可以是任意類型的,所以用它來處理一些東西的時候很不方便,好在React的React.Children提供了處理this.props.children的一些方法:React.Children.map(),React.Children.forEach(),React.Children.count()React.Children.only()React.Children.toArray(),通常與React.cloneElement()結合使用來操作this.props.children。

屬性驗證:定義外部組件(父組件)傳遞的屬性值類型是否符合組件定義的類型要求(一般在通用組件定義時使用)

propsTypes:在React15.5之前可以通過React.PropTypes 進行屬性驗證,之后我們需要借助prop-types庫。

// 1.引入 prop-types 庫
npm install --save prop-types

// 2.導入prop-types
import PropTypes from 'prop-types';

// 3.定義子組件
export default class  PropsTest extends Component{
    // 設置props的默認值
    static defaultProps={ name: 'xiao ming', age: 18, gender: 'man'}
    //約束的關鍵就是這里在定義屬性的時候指定屬性的類型,類似安卓private String name;
    static propTypes={
        name: PropTypes.string,
        age: PropTypes.number,
        gender: PropTypes.string.isRequired
    }
    render(){
        //在這里我們使用props中的name屬性
          return (
            <Text>
              {this.props.name}+' age:'+{this.props.age}+'  gender:'+{this.props.gender}
            </Text>
          )
    }
}

// 4.定義父組件,并在父組件中調用子組件
export default class  HomePage extends Component{
    render(){
       const params = { name: 'daming', age: 20, gender: 'man' }
       return <PropsText {...params}/>
    }
}

5.state

我們使用兩種數據來控制一個組件:props和state。props是在父組件中指定,而且一經指定,在被指定的組件的生命周期中則不再改變。 對于需要改變的數據,我們需要使用state。state 的工作原理和 React.js 完全一致。
一般來說,你需要在 constructor 中初始化state(譯注:這是 ES6 的寫法,早期的很多 ES5 的例子使用的是 getInitialState 方法來初始化 state,這一做法會逐漸被淘汰),然后在需要修改時調用setState方法,每次調用setState都會重新調用組件render()方法。有幾個點需要注意:

  1. 一切界面變化都是狀態state變化
  2. state的修改必須通過setState()方法
  3. setState 是一個 merge 合并操作,只修改指定屬性,不影響其他屬性
  4. setState 是異步操作,修改不會馬上生效,要獲取到新設置的state屬性,需要在setState的回調函數中
export default class  StateTest extends Component{
    // 設置state的默認值
   state = {
    name: '小紅',
    age: 16,
    gender: 'women',
   };
   render(){
         return (
           <Text>
             {this.state.name}+' age:'+{this.state.age}+'  gender:'+{this.state.gender}
           </Text>
         )
   }
}

6.ref

父組件獲取子組件的屬性

// 子組件
export default class  RefTest extends Component{
    // 設置state的默認值
   state = { name: '小白' };
  getName(){
    return this.state.name;
  }
   render(){
         return (
           <Text>
             哈哈哈
           </Text>
         )
   }
}

// 父組件
import RefTest from './RefTest';
export default class  RefFather extends Component{
   render(){
         return (
            <View>
               <Text>
                  你好,{this.refTest.getName()}!
               </Text>
              <RefTest ref ={refTest => this.refTest=refTest} />
            </View>
         )
   }
}

7.樣式

在 React Native 中,你并不需要學習什么特殊的語法來定義樣式。我們仍然是使用 JavaScript 來寫樣式。所有的核心組件都接受名為style的屬性。這些樣式名基本上是遵循了 web 上的 CSS 的命名,只是按照 JS 的語法要求使用了駝峰命名法,例如將background-color改為backgroundColor。
style屬性可以是一個普通的 JavaScript 對象,還可以傳入一個數組——在數組中位置居后的樣式對象比居前的優先級更高,這樣可以間接實現樣式的繼承。

定義樣式

  1. HTML5以 ‘;’ 結尾
    RN 以 ‘,’ 結尾
  2. HTML5的key、value都不加引號
    RN中屬于js對象,key的名字不能出現‘-’,要使用駝峰命名法;如果value為字符串,需要加引號
  3. HTML5中,value如果是數字,需要加單位
    RN中,value是數字不需要加單位

實際開發中組件的樣式會越來越復雜,建議使用StyleSheet.create來集中定義組件的樣式。StyleSheet.create的參數是一個對象,對象中的每個屬性都是以鍵值對的形式定義。

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

const instructions = Platform.select({
  ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu',
  android:
    'Double tap R on your keyboard to reload,\n' +
    'Shake or press menu button for dev menu',
});

type Props = {};
export default class App extends Component<Props> {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>Welcome to React Native!</Text>
        <Text style={styles.instructions}>To get started, edit App.js</Text>
        <Text style={styles.instructions}>{instructions}</Text>
      </View>
    );
  }
}

// StyleSheet.create方式定義樣式
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});


// 通過style直接在組件內定義
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';

export default class FixedDimensionsBasics extends Component {
  render() {
    return (
      <View>
        <View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
        <View style={{width: 100, height: 100, backgroundColor: 'skyblue'}} />
        <View style={{width: 150, height: 150, backgroundColor: 'steelblue'}} />
      </View>
    );
  }
}

8.Flexbox布局

React Native 中使用 flexbox 規則來指定某個組件的子元素的布局。Flexbox 可以在不同屏幕尺寸上提供一致的布局結構。

1.寬高:組件的高度和寬度決定了其在屏幕上顯示的尺寸,也就是大小
2.彈性(Flex)寬高:在組件樣式中使用flex可以使其在可利用的空間中動態地擴張或收縮。一般而言我們會使用flex:1來指定某個組件擴張以撐滿所有剩余的空間。如果有多個并列的子組件使用了flex:1,則這些子組件會平分父容器中剩余的空間(前提是其父容器的尺寸不為零,如果父容器既沒有固定的width和height,也沒有設定flex,則父容器的尺寸為零。其子組件如果使用了flex,也是無法顯示的)。如果這些并列的子組件的flex值不一樣,則誰的值更大,誰占據剩余空間的比例就更大(即占據剩余空間的比等于并列組件間flex值的比)
2.無單位:React Native 中的尺寸都是無單位的,表示的是與設備像素密度無關的邏輯像素點,確保了在任何不同dpi的設備上顯示都不會發生變化

React Native 中的 Flexbox 的工作原理和 web 上的 CSS 不同的是:

1.flexDirection:默認值是column,而不是row,而flex也只能指定一個數字值
2.alignItems:默認值是stretch,而不是flex-start
3.flex:只能指定一個參數并且是數字,而Web CSS中可以接受多參數
4.不支持屬性:align-content,flex-basis,order,flex-flow,flex-grow,flex-shrink

9.網絡請求

很多移動應用都需要從遠程地址中獲取數據或資源。你可能需要給某個 REST API 發起 POST 請求以提交用戶數據,也可能只是需要從某個服務器上獲取一些靜態內容。
在React Native中是使用fetch來實現網絡請求的??梢詤⒖?a target="_blank">Fetch 請求文檔來查看所有可用的參數。

發起請求
要從任意地址獲取內容的話,只需簡單地將網址作為參數傳遞給 fetch 方法即可

fetch('https://mywebsite.com/mydata.json');

Fetch 還有可選的第二個參數,可以用來定制 HTTP 請求一些參數,可以指定 header 參數,或是指定使用 POST 方法,或是提交數據等等:

fetch('https://mywebsite.com/endpoint/', {
  method: 'POST',
  headers: {
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    firstParam: 'yourValue',
    secondParam: 'yourOtherValue',
  }),
});

提交數據的格式關鍵取決于 headers 中的Content-Type。Content-Type有很多種,對應 body 的格式也有區別。到底應該采用什么樣的Content-Type取決于服務器端,所以請和服務器端的開發人員溝通確定清楚。常用的'Content-Type'除了上面的'application/json',還有傳統的網頁表單形式,如:

fetch('https://mywebsite.com/endpoint/', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
  },
  body: 'key1=value1&key2=value2',
});

使用 Chrome 調試目前無法查看到 React Native 中的網絡請求,可以使用第三方的react-native-debugger來進行查看。

10.基礎組件

View
在Web開發中,div是最重要的一個元素,是頁面布局的基礎。在React Native開發中,View組件的作用類似于div,是最基本的組件,被看作是容器組件,不管是顯示一個文本還是輸入框,都可以把它們放在View組件內部。不論在什么平臺上,View 都會直接對應一個平臺的原生視圖,無論它是 UIView、div還是 android.view.View

Text
顯示文本內容的組件

Image
顯示圖片內容的組件。用于顯示多種不同類型圖片的 React 組件,包括網絡圖片、靜態資源、臨時的本地圖片、以及本地磁盤上的圖片(如相冊)等

TextInput
文本輸入框組件

ScrollView
可滾動的容器視圖。封裝了平臺的ScrollView(滾動視圖)的組件,同時還集成了觸摸鎖定的“響應者”系統。
必須要有一個確定的高度,在確保父級容器已經設置了高度情況下,可以通過設置flex: 1以使其自動填充父容器的空余空間

FlatList組件相比:ScrollView會簡單粗暴地把所有子元素一次性全部渲染出來,毫無疑問這會導致一些性能問題,而FlatList會惰性渲染子元素,只在它們將要出現在屏幕中時才開始渲染。除非你要渲染的數據特別少,否則你都應該盡量使用FlatList,此外FlatList還可以方便地渲染行間分隔線,支持多列布局,無限滾動加載等等

StyleSheet
提供類似CSS樣式表的樣式抽象層

11.交互控件

常見的跨平臺的交互控件
Button
一個簡單的跨平臺的按鈕控件。組件的樣式是固定的,可以使用TouchableOpacity或是TouchableNativeFeedback組件來定制自己所需要的按鈕

Picker
在iOS和Android上調用各自原生的選擇器控件。

<Picker
  selectedValue={this.state.language}
  style={{ height: 50, width: 100 }}
  onValueChange={(itemValue, itemIndex) => this.setState({language: itemValue})}>
  <Picker.Item label="Java" value="java" />
  <Picker.Item label="JavaScript" value="js" />
</Picker>

Slider
滑動數值選擇器

Switch
開關,跨平臺通用受控組件。通過onValueChange回調來更新value屬性以響應用戶的操作。如果不更新value屬性,組件只會按一開始給定的value值來渲染且保持不變

12.列表視圖

只會渲染當前屏幕可見的元素(懶加載),這樣有利于顯示大量的數據
FlatList
常用功能

1.完全跨平臺。
2.支持水平布局模式。
3.行組件顯示或隱藏時可配置回調事件。
4.支持單獨的頭部組件。
5.支持單獨的尾部組件。
6.支持自定義行間分隔線。
7.支持下拉刷新。
8.支持上拉加載。
9.支持跳轉到指定行(ScrollToIndex)

SectionList
類似FlatList,多了分組顯示。
常用功能

1.完全跨平臺。
2.行組件顯示或隱藏時可配置回調事件。
3.支持單獨的頭部組件。
4.支持單獨的尾部組件。
5.支持自定義行間分隔線。
6.支持分組的頭部組件。
7.支持分組的分隔線。
8.支持多種數據源結構
9.支持下拉刷新。
10.支持上拉加載。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,546評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,570評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,505評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,017評論 1 313
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,786評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,219評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,287評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,438評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,971評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,796評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,995評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,540評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,230評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,918評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,697評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374

推薦閱讀更多精彩內容