React Native 十萬個為什麼(開發問題整理)
阿新 • • 發佈:2019-01-26
掃碼加入react-native技術交流群。定期會分享react native 技術文章,移動技術乾貨,精彩文章技術推送。歡迎各位大牛, React Native技術愛好者加入交流!
在ScrollView中切換輸入框<TextInouput>,為什麼需要點選兩次才能實現?
答:這是由於ScrollView也會相應點選事件,解決這個問題,只需要在ScrollView元件中新增兩個屬性:
keyboardShouldPersistTaps='always'
keyboardDismissMode={'on-drag'}
Android裝置中InteractionManager.runAfterInteractions中的回撥方法不執行?
InteractionManager.runAfterInteractions(() => {
// ...耗時較長的同步的任務...
});
造成這種問題原因,主要是因為動畫執行緒搶奪導致衝突,例如轉場動畫,自定義動畫導致。解決方式有兩種:
(1)自定義動畫設定屬性useNativeDriver,開啟原生硬體動畫渲染支援
(2)自定義InteractionManager的runAfterInteractions:
import { InteractionManager } from "react-native"; export default { ...InteractionManager, runAfterInteractions: f => { // ensure f get called, timeout at 500ms // @gre workaround https://github.com/facebook/react-native/issues/8624 let called = false; const timeout = setTimeout(() => { called = true; f() }, 500); InteractionManager.runAfterInteractions(() => { if (called) return; clearTimeout(timeout); f(); }); } };
點選列表頁中的Item ,傳遞不同的引數到詳情頁,顯示不同的內容,再點選慢的情況下沒有問題,再點選快的時候會出現資料不更新的情況,導致資料顯示錯誤,怎麼解決?
答:這是因為原有的詳情頁還沒有解除安裝,然後就點選了列表頁的item,然後傳引數到詳情頁, 此時不會建立新的詳情頁,原有詳情頁會接收傳過來的引數通過 componentWillReceiveProps 方法,此時需要判斷相關資料是不是需要重新渲染(或者說現在的詳情頁需要顯示的資料和上 一次的詳情頁顯示的資料是不是一致),如果需要重新渲染,則重新初始化資料,重新調介面, 重新渲染介面。 // 1. 必須在componentWillReceiveProps(nextProps)生命週期中接受傳遞的引數 // 2. 該生命週期方法中的引數必須叫做nextProps // 3. 所有傳遞過來的引數都包含在nextProps引數中 // 4. 以nextProps.PARAM_NAME的方式獲取指定的引數 componentWillReceiveProps(nextProps) { /** * todo 判斷是不是第一次進入該介面或者說該介面需要重新渲染, * todo 主要用於元件還沒有解除安裝,就又呼叫了該元件,因此會走componentWillReceiveProps方法。 */ let isFirstComeIn = nextProps.rowData.order_id != this.props.rowData.order_id;//im InteractionManager.runAfterInteractions(() => { if (isFirstComeIn) { this.onFirstComeIn(); return; } }); }
在react-native中,如果一個元件資料的重新整理需要聯網,在網路資料返回後更新頁面,這個時候,需要在重新整理頁面的時候判斷一下該元件是否處於載入狀態,如果不在載入狀態,那麼不應該呼叫this.setState()去更新state,可以按以下方法來進行處理:
工具類:BaseCommon.js
/**
* BaseCommon
* 公共邏輯處理
*/
'use strict';
import React from "react";
export default class BaseCommon {
constructor(props) {
}
componentWillMount() {
}
componentDidMount() {
this.mounted = true;
}
componentWillUnmount() {
this.mounted = false;
}
}
通過BaseCommon.js 來對當前元件進行載入狀態判斷
export default class IndexScreen extends BaseComponent {
// 構造
constructor(props) {
super(props);
this.baseCommon = new BaseCommon({ ...props, });
// 初始狀態
this.state = {
};
}
componentDidMount() {
this.baseCommon.componentDidMount();
fetch().then((response) => {
this.baseCommon.mounted && this.setState({});
})
}
componentWillMount() {
this.baseCommon.componentWillMount();
}
componentWillUnmount() {
this.baseCommon.componentWillUnmount();
}
}