React Native常見問題解答(一)
呼叫setState之後發生了什麼?
在程式碼中呼叫setState函式之後,
1. React會將傳入的引數物件與元件當前的狀態合併,然後觸發所謂
的調和過程(Reconciliation)。
2. 經過調和過程,React會以相對高效的方式根據新的狀態構建React。
3. 元素樹並且著手重新渲染整個UI介面。
4. 在React得到元素樹之後,React會自動計算出新的樹與老樹的節點差異,
5. 根據差異對介面進行最小化重渲染。在差異計算演算法中,React能夠相對精確地知道哪些位置發生了改變
以及該如何改變,這就保證了按需更新,而不是全部重新渲染。
在生命週期中的哪一步你應該發起AJAX請求?為什麼?
將AJAX請求放到componentDidMount函式中執行。
原因如下:
1. React 下一代調和演算法Fiber會通過開始或停止渲染的方式優化效能,其會影響到componentWillMount
的觸發次數。對於componentWillMount這個生命週期函式的條用次數會變得不確定,React可能會多次頻繁呼叫componentWillMount。如果我們將AJAX請求放到componentWillMount函式中,那麼顯而易見
其會被觸發多次,自然也就不是好的選擇。
2. *如果我們將AJAX請求放置在生命週期的其他函式中,我們並不能保證請求僅在元件掛載完畢後
才會要求響應。如果我們的資料請求在元件掛載之前就完成,並且呼叫了setState函式將資料新增到
元件狀態中,對於未掛載的元件則會報錯。而在componentDidMount函式中進行AjAX請求則能有效避免
這個問題。
簡述React元件的生命週期
元件的生命週期可分成三個狀態:
1. Mounting:已插入真實DOM
2. Updating:正在被重新渲染
3. Unmounting:已移出真實DOM
生命週期的方法有:
- componentWillMount 在渲染錢呼叫,在客戶端也在伺服器
- componentDidMount 在第一次渲染後呼叫,只在客戶端。之後元件已經生成了對應的DOM結構,可以通過
this.getDOMNode()來進行訪問。如果你想和其他JavaScript框架一起使用,可以在這個方法中呼叫setTimeout,
setInterval或者傳送AJAX請求等操作(防止非同步操作阻塞UI)。
- componentWillReceiveProps 在元件接收到一個新的prop時被呼叫。這個方法在初始化render時不會被呼叫。
- shouldComponentUpdate 返回一個布林值。在元件接收到新的props或者state時被呼叫。在初始化時或者使用
forceUpdate時不被呼叫。可以在你確認不需要更新元件時使用。
- componentWillUpdate 在元件接收到新的props或者state但還沒有render時被呼叫。在初始化時不會被呼叫。
- componentDidUpdate 在元件完成更鬧心後立即呼叫。在初始化時不會被呼叫。
- componentWillUnmount 在元件從DOM中移除的時候立刻被呼叫。
React中keys的作用是什麼?特點?並舉例說明key的用法。
作用: keys是React用於追蹤哪些列表中元素被修改,被新增或者被移除的輔助標識。
render() {
return(
<ul>
{ this.state.list.map(({item, key}) => {
return <li key={key}>{item}</li>
})}
</ul>
);
}
在開發過程中,我們需要保證某個元素的key在 其同級元素中具有唯一性。在React Diff演算法
中React會藉助元素額key值來判斷該元素是新近建立的還是被移動而來的元素,從而減少不必要
的元素重渲染。此外,React還需要藉助Key值來判斷元素與本地狀態的關聯關係,因此我們絕不可忽視轉換
函式中Key的重要性。
react native網路圖片載入不出來的原因是什麼?怎麼解決?
在IOS9版本以後,預設的網路請求是https,如果是http請求,需要手動解決。
- 找到info.plist檔案,用Xcode開啟。
- 找到App Transport Security Settings選項下的子選項Allow Arbitrary Loads
- 將Allow Arbitrary Loads 設定為YES
假設資料來源為rows=[“row1”,”row2”,”row3”],請用listView展示rows的每一項
import React, { Component} from 'react';
import {
ListView,
View,
Text
} from 'react';
export default class MyListView from Component {
constructor(props) {
super(props)
var ds = ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2
});
this.state = {
dataSource: ds.cloneWidthRows(rows)
}
}
_renderRow(item) {
return (
<View>
<Text>{item}</Text>
</View>
);
}
render() {
return (
<View style={{ flex: 1 }}>
<ListView
renderRow={ this._renderRow.bind(this) }
dataSource={ this.state.dataSource }
/>
</View>
);
}
}
假設我有一個元件叫做FirstPage,請用Navigator實現以FirstPage為首頁的效果
import React, { Component} from 'react';
import {
Navigator
} from 'react-native';
export default class Nav extends Component {
render() {
initialRoute = {
component: FirstPage,
nextPass: {}
}
return (
<Navigator
initialRoute={ initialRoute }
configureScene={ (route) => Navigator.SceneConfigs.PushFromRight }
renderScene={ (route, navigator) => {
// 要渲染的頁面
var component = route.component;
// 渲染元件時,將元件的屬性也傳遞過去
return <Navigator { ...route.nextPass } route={ route } navigator={ navigator } />;
/>
);
}
}
請用TabBarIOS實現一個標籤欄,其中標籤欄包括兩個標籤,分別為首頁電影。其中首頁預設被選中
import React, { Component } from 'react';
import {
TabBarIOS,
View,
Text
} from 'react-native';
class HomeComponent extends Component {
render() {
return (
<View>
<Text>這是首頁頁面</Text>
</View>
);
}
}
class MovieComponent extends Component {
render() {
return (
<View>
<Text>這是電影頁面</Text>
</View>
);
}
}
export default class TitleComponent extends Component {
render() {
return (
<TabBarIOS>
<TabBarIOS.Item
title="首頁"
selected={ true }
>
<HomeComponent/>
</TabBarIOS.Item>
<TabBarIOS.Item
title="電影"
>
<MovieComponent/>
</TabBarIOS.Item>
</TabBarIOS>
);
}
}
shouldComponentUpdate的作用是啥以及為何它這麼重要?
shouldComponetUpdate允許我們手動地判斷是否要進行元件更新,根據元件的應用場景設定函式的合理返回值
能夠幫助我們避免不必要的更新。
為什麼我們需要使用React提供的Children API 而不是Javascript的map?
props.children並不一定是陣列型別,臂如下面這個元素:
<Parent>
<h1>Welcom</h1>
</Parent>
如果我們使用props.children.map函式來遍歷時會受到異常提示,因為在這種情況下props.children
是物件(object)而不是陣列(array)。React當且僅當超過一個子元素的情況下會將props.children設定為陣列,就像
下面這個程式碼片:
<Parent>
<h1>Welcom</h1>
<h2>Hello World</h2>
</Parent>
這也就是我們優先選擇使用React.Children.map函式的原因,其已經將props.children不同型別的情況
考慮在內了。