React-Native采坑總結


1.zIndex

在Android上使用zIndex來控制組件的層級,會遇到元素不顯示的問題。
解決方案:
盡量改變組件的順序,而不用zIndex
盡量不要使用zIndex來控制組件的層級,默認情況下,使用position: 'absolute'后,后面的元素會默認覆蓋在前面的元素之上。所以刪除zIndex,改變一下組件的順序就OK啦。
issues: https://github.com/facebook/react-native/issues/8968 

2.borderStyle:'dashed'

目前,Android上,如果想要實現一條水平方向的虛線,一開始想到的肯定是:

border: {
  borderColor: 'red',
  borderWidth: 0,
  borderBottomWidth: 1,
  borderStyle: 'dashed'
}

但是實際上,這樣是不會生效的,目前Android還不支持某一邊設置虛線。
解決方案:
方案一:假設我們想要一個線寬為h的水平虛線,設置一個高度為h的view,里面給一個view設置四邊都是dashed的邊框,borderWidth為h,高度為0,然后外層設置overflow: 'hidden'但是,你會發現,不管你怎么overflow,都是沒用的,Android照樣會渲染出兩個邊框,看起來overflow也沒有起作用。
方案二:換一種思路,再弄一個view,高度為h,背景顏色設置成你想要的顏色,然后把下面的border覆蓋掉。
此外,也可以關注下這個issue: Border is invisible when using borderStyle='dashed' with borderBottom #7838

3.TouchableOpacity等可點擊組件,有時候點擊不觸發onPress

這個問題,如果你只是在代碼里面放了類似下面的代碼:

<TouchableOpacity 
    style={styles.btn}onPress={this.onPress.bind(this)}>
  <Text>立即預定</Text>
</TouchableOpacity>

並且onPress回調里面,並沒有做太多的邏輯,或者導致重新渲染。
那么,你沒有必要懷疑是你代碼的問題。RN對部分國產手機那些自定義的手勢支持不好。

4.[style]Android上Text默認的字體顏色,不是black,不是black,不是black

如果在Android上面,不顯示地給Text添加color,那么顯示出來的字體顏色就是灰色。跟iOS的表現不一致;
解決方案:
方案一:給每個Text都設置color

不足:每次都設置color。比較繁瑣

方案二:寫一個自定義組件

比如MyText,這個Text設置顏色,每次使用 xxx 就默認為你設置的顏色了。
不足:多出來了一個新的組件,也比較繁瑣。
多出來了一個新的組件,也比較繁瑣。

方案三:設置默認props

在入口文件里面寫上默認的style,比如:
Text.defaultProps.sytle = { 'color': '#212121'}

5.[ListView] renderRow 使用 this.state.xxx 屬性,setState({xxx:'xxx'})的時候 ListView沒有重新渲染

解決方案 重新設置 ListView 的 dataSource

6.[console] console.log()打印出來的對象,值不是最准確的,可能會受后面執行代碼的影響。

7.[網絡請求] 安卓機型連代理,有時抓不到請求

RN-andriod 用的網絡模塊是okhttp。這個模塊有一個類似代理路由的功能。通過代理(比如charles)發送一個請求時,如果該請求timeout或者error了(比如abort),okhttp在下次發送請求時可能不走charles。導致請求發出去了,但是charles抓不到。

8.[ios模擬器] 配置localhost:port之后,請求不到js

如果沒有提示說服務沒有啟動,提示404。基本上就是你電腦上沒有配置localhost對應的host。可能有寫hosts工具切換的時候,把localhost弄掉了。自己加回來:

127.0.0.1 localhost

9.RN0.46以上版本,使用touchable視圖包裹TextInput組件,touchable視圖上的onPress事件不能觸發

<TouchableOpacity>
    <TextInput />     <---- touch not working here
    <Text>Text</Text>      <---- touch working here
</TouchableOpacity>

這個屬於官方未修復的問題,詳見https://github.com/facebook/react-native/issues/14958
臨時解決方案
TextInput包裹在一個View中,給這個視圖的pointEvents的屬性設置為none

<TouchableOpacity
onPress={()=>{console.log('press')}}>
   <View pointerEvents='none'>
      <TextInput editable={false} />
   </View>
</TouchableOpacity>

10.TextInput問題

TextInput在安卓上默認有一個底邊框,同時會有一些padding。如果要想使其看起來和iOS上盡量一致,則需要設置padding: 0,同時設置underlineColorAndroid="transparent"來去掉底邊框。

11.內容對齊問題

新增的展示內容與原有的結構往往不同,上下對齊需要通過margin和padding來調整。以下是調整中遇到的問題及解決:

1.ios和adr的表現不一致,測試時需要兩種機型都看下,在style中根據platform分別調整數值。

2.開發完后可能肉眼看覺得ok,但ui那邊是通過畫線驗收,如上圖所示。所以我們最好完了也用線對齊看看,減少修改的次數。

3.一行文字中同時存在漢字、數字、特殊符號時,它們有時不會底對齊,又或者ui要求垂直居中。這個可以通過lineHeight和paddingTop來調整。

4.必要時會用到0點幾這種數值。

5.一行字里有文字有數字不對齊這種,也可以換個字體解決哈~ Helvetica Verdana Cochin 都可以。

12.RN中組件陰影解決方案

不知從什么時候開始,公司的UI偏愛給所有模塊加上陰影效果,對於IOS系統,RN支持通過style設置陰影,但是Android系統着實讓人頭痛,在實踐過程中先后使用過多種方法。

<View elevation={5} style={styles.container}>
   <Text>Hello World !</Text>
 </View>
  • IOS陰影實現方案

RN在ios系統上支持一系列陰影的樣式屬性,但這些屬性在Andriod上不會生效。

container : {
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowRadius: 2,
    shadowOpacity: 0.2
}
  • Android陰影實現方案

(1)使用elevation屬性

<View elevation={2} style={styles.container}>
   <Text>Hello World !</Text>
</Vie
container : {
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowRadius: 2,
    shadowOpacity: 0.2,
    elevation: 2
}

這個屬性可以寫在樣式里也可以直接當做組件的屬性,使用這個屬性可以產生一定的陰影效果,但是陰影顏色、透明度等都不能定制,大多數情況下並不滿足UI的要求。

(2)使用Image組件做背景

<Image style={styles.bgImg} source={{uri:bgImg}} resizeMode="stretch">
    <YourView />
</Image>

或者

<View>
    <Image style={styles.bgImg} source={{uri:bgImg}} resizeMode="stretch" />
    <YourView />
</View>

設置Image的樣式未絕對定位鋪滿容器,類似於下面的ImageBackground,RN0.46.4加入了一個組件ImageBackground,可以像上面類似的方式使用.源碼非常簡單,https://github.com/facebook/react-native/blob/master/Libraries/Image/ImageBackground.js

'use strict';
const Image = require('Image');
const React = require('React');
const StyleSheet = require('StyleSheet');
const View = require('View');
const ensureComponentIsNative = require('ensureComponentIsNative');
import type {NativeMethodsMixinType} from 'ReactNativeTypes';

class ImageBackground extends React.Component {
  setNativeProps(props: Object) {
    // Work-around flow
    const viewRef = this._viewRef;
    if (viewRef) {
      ensureComponentIsNative(viewRef);
      viewRef.setNativeProps(props);
    }
  }

  _viewRef: ?NativeMethodsMixinType = null;

  _captureRef = ref => {
    this._viewRef = ref;
  };

  render() {
    const {children, style, imageStyle, imageRef, ...props} = this.props;
    return (
      <View style={style} ref={this._captureRef}>
        <Image
          {...props}
          style={[
            StyleSheet.absoluteFill,
            {
              // Temporary Workaround:
              // Current (imperfect yet) implementation of <Image> overwrites width and height styles
              // (which is not quite correct), and these styles conflict with explicitly set styles
              // of <ImageBackground> and with our internal layout model here.
              // So, we have to proxy/reapply these styles explicitly for actual <Image> component.
              // This workaround should be removed after implementing proper support of
              // intrinsic content size of the <Image>.
              width: style.width,
              height: style.height,
            },
            imageStyle,
          ]}
          ref={imageRef}
        />
        {children}
      </View>
    );
  }
}

module.exports = ImageBackground;

類似這種使用圖片都陰影背景的方式,一般設置里面內容的背景色為透明色,在實踐過程中有時會出現背景圖片還未加載完成,但里面的內容已加載完成的情況,會出現背景的一個跳變。

<Image style={styles.bgImg} source={{uri:bgImg}} resizeMode="stretch">
    <View style={[styles.bg,StyleSheet.absoluteFill]}></View>
    <YourView/>
</Image>

目前我采用的方案是使用一個單獨的View墊底,較好的解決了這個問題。但是圖片拉伸變形的問題估計沒有好的解決方案了。

(3).使用“點9圖(.9圖)”封裝一個Native組件
Android系統支持一個牛叉的東西叫“點9圖”,以前真沒聽過,估計原生開發知道這個東西,它有一個特點是拉伸后不會變形,包括圓角。關於點9圖的概念可以參考.9.PNG是啥?.關於如何原生封裝一個帶有點9圖背景的組件,我也不知道啊,這部分是原生開發實現的。參考React Native顯示點9圖片,也許有幫助,現在我們業務線都是使用這種方式,效果比較好。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM