1.React Native組件
獨立的、可重用的模塊。
有3種方式可以創(chuàng)建組件:1. ES6方式創(chuàng)建;2. ES5方式創(chuàng)建;3.函數(shù)式定義無狀態(tài)組件方式
// ES6方式創(chuàng)建組件
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方式創(chuàng)建組件
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;
// 無狀態(tài)組件方式:沒有this,沒有生命周期函數(shù)
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組件擁有一樣的生命周期函數(shù),
分為3種狀態(tài):
Mounting:掛載,已插入真實Dom
Updating:更新,正在被重新渲染
Unmounting:卸載,已移出真實Dom
4個階段
創(chuàng)建:只調(diào)用getDefaultProps方法
實例化:getInitialState,componentWillMount,render(渲染并返回一個虛擬Dom),componentDidMount(根據(jù)虛擬Dom對象創(chuàng)建真實Dom,可以在此獲取Dom節(jié)點)
更新:static getDerivedStateFromProps(props, state);shouldComponentUpdate(nextProps, nextState);render();getSnapshotBeforeUpdate(props, state);componentDidUpdate(preProps, preState, snapshot)
銷毀:componentWillUnmount
3.組件的導(dǎo)入與導(dǎo)出
// ES6:export導(dǎo)出,import導(dǎo)入
// 導(dǎo)出
export default class App extends Component{
render() {
return (
<Text style={styles.welcome}>Welcome to React Native!</Text>
);
}
}
// 導(dǎo)入
import App from './App';
// ES5: module.export導(dǎo)出,import導(dǎo)入
// 導(dǎo)出
var App = React.createClass({
render(){
return (
<Text style={styles.welcome}>Welcome to React Native!</Text>
);
}
})
module.exports = App;
//導(dǎo)入
import App from './App';
4.props
React相當(dāng)于MVC的View層,負(fù)責(zé)展示,并不涉及到數(shù)據(jù),但是組件在使用的過程中有兩個屬性是和數(shù)據(jù)有關(guān)的:props和state
props:組件自身的屬性,一般用于嵌套的內(nèi)外層組件中,由父組件傳給子組件,負(fù)責(zé)傳遞信息,也可以用于屬性約束和驗證。(props對象中的屬性與組件屬性一一對應(yīng)--除this.props.children之外,不要直接修改props屬性中的值)
...this.props:可以將父組件中傳遞的全部屬性復(fù)制給子組件
this.props.children:組件的所有子節(jié)點。它的返回值可以是任意類型的,所以用它來處理一些東西的時候很不方便,好在React的React.Children提供了處理this.props.children的一些方法:React.Children.map(),React.Children.forEach(),React.Children.count(),React.Children.only(),React.Children.toArray(),通常與React.cloneElement()結(jié)合使用來操作this.props.children。
屬性驗證:定義外部組件(父組件)傳遞的屬性值類型是否符合組件定義的類型要求(一般在通用組件定義時使用)
propsTypes:在React15.5之前可以通過React.PropTypes 進(jìn)行屬性驗證,之后我們需要借助
prop-types庫。
// 1.引入 prop-types 庫
npm install --save prop-types
// 2.導(dǎo)入prop-types
import PropTypes from 'prop-types';
// 3.定義子組件
export default class PropsTest extends Component{
// 設(shè)置props的默認(rèn)值
static defaultProps={ name: 'xiao ming', age: 18, gender: 'man'}
//約束的關(guān)鍵就是這里在定義屬性的時候指定屬性的類型,類似安卓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.定義父組件,并在父組件中調(diào)用子組件
export default class HomePage extends Component{
render(){
const params = { name: 'daming', age: 20, gender: 'man' }
return <PropsText {...params}/>
}
}
5.state
我們使用兩種數(shù)據(jù)來控制一個組件:props和state。props是在父組件中指定,而且一經(jīng)指定,在被指定的組件的生命周期中則不再改變。 對于需要改變的數(shù)據(jù),我們需要使用state。state 的工作原理和 React.js 完全一致。
一般來說,你需要在 constructor 中初始化state(譯注:這是 ES6 的寫法,早期的很多 ES5 的例子使用的是 getInitialState 方法來初始化 state,這一做法會逐漸被淘汰),然后在需要修改時調(diào)用setState方法,每次調(diào)用setState都會重新調(diào)用組件render()方法。有幾個點需要注意:
- 一切界面變化都是狀態(tài)state變化
- state的修改必須通過setState()方法
- setState 是一個 merge 合并操作,只修改指定屬性,不影響其他屬性
- setState 是異步操作,修改不會馬上生效,要獲取到新設(shè)置的state屬性,需要在setState的回調(diào)函數(shù)中
export default class StateTest extends Component{
// 設(shè)置state的默認(rèn)值
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{
// 設(shè)置state的默認(rèn)值
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 中,你并不需要學(xué)習(xí)什么特殊的語法來定義樣式。我們?nèi)匀皇鞘褂?JavaScript 來寫樣式。所有的核心組件都接受名為style的屬性。這些樣式名基本上是遵循了 web 上的 CSS 的命名,只是按照 JS 的語法要求使用了駝峰命名法,例如將background-color改為backgroundColor。
style屬性可以是一個普通的 JavaScript 對象,還可以傳入一個數(shù)組——在數(shù)組中位置居后的樣式對象比居前的優(yōu)先級更高,這樣可以間接實現(xiàn)樣式的繼承。
定義樣式
- HTML5以 ‘;’ 結(jié)尾
RN 以 ‘,’ 結(jié)尾- HTML5的key、value都不加引號
RN中屬于js對象,key的名字不能出現(xiàn)‘-’,要使用駝峰命名法;如果value為字符串,需要加引號- HTML5中,value如果是數(shù)字,需要加單位
RN中,value是數(shù)字不需要加單位
實際開發(fā)中組件的樣式會越來越復(fù)雜,建議使用StyleSheet.create來集中定義組件的樣式。StyleSheet.create的參數(shù)是一個對象,對象中的每個屬性都是以鍵值對的形式定義。
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直接在組件內(nèi)定義
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 規(guī)則來指定某個組件的子元素的布局。Flexbox 可以在不同屏幕尺寸上提供一致的布局結(jié)構(gòu)。
1.寬高:組件的高度和寬度決定了其在屏幕上顯示的尺寸,也就是大小
2.彈性(Flex)寬高:在組件樣式中使用flex可以使其在可利用的空間中動態(tài)地擴(kuò)張或收縮。一般而言我們會使用flex:1來指定某個組件擴(kuò)張以撐滿所有剩余的空間。如果有多個并列的子組件使用了flex:1,則這些子組件會平分父容器中剩余的空間(前提是其父容器的尺寸不為零,如果父容器既沒有固定的width和height,也沒有設(shè)定flex,則父容器的尺寸為零。其子組件如果使用了flex,也是無法顯示的)。如果這些并列的子組件的flex值不一樣,則誰的值更大,誰占據(jù)剩余空間的比例就更大(即占據(jù)剩余空間的比等于并列組件間flex值的比)
2.無單位:React Native 中的尺寸都是無單位的,表示的是與設(shè)備像素密度無關(guān)的邏輯像素點,確保了在任何不同dpi的設(shè)備上顯示都不會發(fā)生變化
React Native 中的 Flexbox 的工作原理和 web 上的 CSS 不同的是:
1.flexDirection:默認(rèn)值是
column,而不是row,而flex也只能指定一個數(shù)字值
2.alignItems:默認(rèn)值是stretch,而不是flex-start
3.flex:只能指定一個參數(shù)并且是數(shù)字,而Web CSS中可以接受多參數(shù)
4.不支持屬性:align-content,flex-basis,order,flex-flow,flex-grow,flex-shrink
9.網(wǎng)絡(luò)請求
很多移動應(yīng)用都需要從遠(yuǎn)程地址中獲取數(shù)據(jù)或資源。你可能需要給某個 REST API 發(fā)起 POST 請求以提交用戶數(shù)據(jù),也可能只是需要從某個服務(wù)器上獲取一些靜態(tài)內(nèi)容。
在React Native中是使用fetch來實現(xiàn)網(wǎng)絡(luò)請求的??梢詤⒖?a target="_blank">Fetch 請求文檔來查看所有可用的參數(shù)。
發(fā)起請求
要從任意地址獲取內(nèi)容的話,只需簡單地將網(wǎng)址作為參數(shù)傳遞給 fetch 方法即可
fetch('https://mywebsite.com/mydata.json');
Fetch 還有可選的第二個參數(shù),可以用來定制 HTTP 請求一些參數(shù),可以指定 header 參數(shù),或是指定使用 POST 方法,或是提交數(shù)據(jù)等等:
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
}),
});
提交數(shù)據(jù)的格式關(guān)鍵取決于 headers 中的Content-Type。Content-Type有很多種,對應(yīng) body 的格式也有區(qū)別。到底應(yīng)該采用什么樣的Content-Type取決于服務(wù)器端,所以請和服務(wù)器端的開發(fā)人員溝通確定清楚。常用的'Content-Type'除了上面的'application/json',還有傳統(tǒng)的網(wǎng)頁表單形式,如:
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: 'key1=value1&key2=value2',
});
使用 Chrome 調(diào)試目前無法查看到 React Native 中的網(wǎng)絡(luò)請求,可以使用第三方的react-native-debugger來進(jìn)行查看。
10.基礎(chǔ)組件
View
在Web開發(fā)中,div是最重要的一個元素,是頁面布局的基礎(chǔ)。在React Native開發(fā)中,View組件的作用類似于div,是最基本的組件,被看作是容器組件,不管是顯示一個文本還是輸入框,都可以把它們放在View組件內(nèi)部。不論在什么平臺上,View 都會直接對應(yīng)一個平臺的原生視圖,無論它是 UIView、div還是 android.view.View
Text
顯示文本內(nèi)容的組件
Image
顯示圖片內(nèi)容的組件。用于顯示多種不同類型圖片的 React 組件,包括網(wǎng)絡(luò)圖片、靜態(tài)資源、臨時的本地圖片、以及本地磁盤上的圖片(如相冊)等
TextInput
文本輸入框組件
ScrollView
可滾動的容器視圖。封裝了平臺的ScrollView(滾動視圖)的組件,同時還集成了觸摸鎖定的“響應(yīng)者”系統(tǒng)。
必須要有一個確定的高度,在確保父級容器已經(jīng)設(shè)置了高度情況下,可以通過設(shè)置flex: 1以使其自動填充父容器的空余空間
和
FlatList組件相比:ScrollView會簡單粗暴地把所有子元素一次性全部渲染出來,毫無疑問這會導(dǎo)致一些性能問題,而FlatList會惰性渲染子元素,只在它們將要出現(xiàn)在屏幕中時才開始渲染。除非你要渲染的數(shù)據(jù)特別少,否則你都應(yīng)該盡量使用FlatList,此外FlatList還可以方便地渲染行間分隔線,支持多列布局,無限滾動加載等等
StyleSheet
提供類似CSS樣式表的樣式抽象層
11.交互控件
常見的跨平臺的交互控件
Button
一個簡單的跨平臺的按鈕控件。組件的樣式是固定的,可以使用TouchableOpacity或是TouchableNativeFeedback組件來定制自己所需要的按鈕
Picker
在iOS和Android上調(diào)用各自原生的選擇器控件。
<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
滑動數(shù)值選擇器
Switch
開關(guān),跨平臺通用受控組件。通過onValueChange回調(diào)來更新value屬性以響應(yīng)用戶的操作。如果不更新value屬性,組件只會按一開始給定的value值來渲染且保持不變
12.列表視圖
只會渲染當(dāng)前屏幕可見的元素(懶加載),這樣有利于顯示大量的數(shù)據(jù)
FlatList
常用功能
1.完全跨平臺。
2.支持水平布局模式。
3.行組件顯示或隱藏時可配置回調(diào)事件。
4.支持單獨的頭部組件。
5.支持單獨的尾部組件。
6.支持自定義行間分隔線。
7.支持下拉刷新。
8.支持上拉加載。
9.支持跳轉(zhuǎn)到指定行(ScrollToIndex)
SectionList
類似FlatList,多了分組顯示。
常用功能
1.完全跨平臺。
2.行組件顯示或隱藏時可配置回調(diào)事件。
3.支持單獨的頭部組件。
4.支持單獨的尾部組件。
5.支持自定義行間分隔線。
6.支持分組的頭部組件。
7.支持分組的分隔線。
8.支持多種數(shù)據(jù)源結(jié)構(gòu)
9.支持下拉刷新。
10.支持上拉加載。