React Native初学踩的那些坑

1.react native - expected a component class, got [object Object]

组件引用名称必须是首字母大写 (目前在0.32版本中是可以小写的)

譬如:

import Login from './login';
//文件名称和里面的类名首字母小写都没关系,但是引用的别名必须首字母大写

 2.TextInput不显示

必须要设置TextInput的高度,默认是没有边框的

textInput :{
        height : 40,
        borderColor: 'gray', 
        borderWidth: 1
    }

 3.使用Fetch调用WebService,报错:TypeError: Network request failed

将请求的ip地址localhost(或者127.0.0.1)换成本地的IP地址

4.点击事件

没看文档找了半天,也没有找到啥GestureRecgnizers

  1. TouchableHighlight
  2. TouchableNativeFeedback
  3. TouchableOpacity
  4. TouchableWithoutFeedback

详细的教程:http://blog.csdn.net/liu8021203/article/details/50828044 

5.组合Style

RN支持一系列的样式:在冲突值的情况下,从最右边元素的值将会优先

style={[styles.menuItem,{backgroundColor:'red'}]}

使用[]讲多个style包含起来,中间用逗号隔开

详细教程:http://www.cnblogs.com/suxun/p/5222175.html

6.编码问题

RN中m默认的全部使用的UTF-8的编码,服务器最好采用相同的编码格式,否则要自己进行转换

7.fetch

该方法没有完善,很多必须的东西都没有,譬如无法设置超时时间

可以直接使用XMLHttpRequest或者自己封装下fetch

http://bbs.reactnative.cn/topic/1926/%E5%85%B3%E4%BA%8Ereact-native-fetch-%E8%B6%85%E6%97%B6%E5%A4%84%E7%90%86%E6%80%8E%E4%B9%88%E5%81%9A/2

http://bbs.reactnative.cn/topic/741/fetch%E8%AE%BF%E9%97%AE%E7%BD%91%E7%BB%9C%E6%97%B6%E5%80%99%E6%80%8E%E4%B9%88%E8%AE%BE%E7%BD%AE%E8%B6%85%E6%97%B6%E5%B1%9E%E6%80%A7/3

8.如何在Image控件的Source属性传入变量

 https://github.com/facebook/react-native/issues/2481

9.如果在Start根据本地的缓存判断是否跳转到登录界面或者主界面

该问题的难点不是判断,而是异步,AppStorage只有异步方法

http://react-china.org/t/react-native/1921/3

10.调用接口的时候,提交键值对

前面的做法就是直接使用一个Map对象,添加键值对,然后直接通过工具转换成JSON字符串

 1)post提交数据的时候,像对象这种,还是需要转换成JSON字符串提交,负责提交的是[Object]

 2)ES6中的Map对象,无法使用JSON.stringify转换,因为Map对象的键可以接受任意类型的对象

  

The keys of a map can be anything, including objects. But JSON syntax only allows strings as keys. So it's impossible in a general case.

My keys are guaranteed to be strings and my values will always be lists
In this case, you can use a plain object. It will have these advantages:

It will be able to be stringified to JSON.
It will work on older browsers.
It might be faster.

所以,直接使用普通的对象就行了,譬如:

let dict={
   userName:'XXX',
   password:'YYY'
};
let requestStr=JSON.stringify(dict);

11.JSON转换失败

JSON.parse()方法转换的时候要求必须是双引号,
而window.eval()不必要
所以React Natve接收到的必须全部是双引号

12.WebView之injectedJavaScript

推荐使用第三方的组件: https://github.com/alinz/react-native-webview-bridge

巨坑:在injectedJavaScript中返回到WebView的执行代码,里面千万不要包括注释,即// 这种东西,iOS上面并不会有任何问题,但是android上面会直接中断执行

2号坑:在html文件中的js或者RN注入的js,千万不要使用ES6的语法,因为低版本的Android(5.1不行,6.0支持)和iOS的浏览器内核不支持ES6语法

http://kangax.github.io/compat-table/es6/

通过上面可以看出,手机不通版本的系统支持的程度不同,所以会出现不同的手机,有的运行正常,有的运行错误的情况

13.Java使用WritableArray(其他的应该也是同样的道理)

场景:由于包保存一个数据,在数据的获取过程中,将结果全部保存在一个全局的WritableArray对象中,然后,每次添加数据的时候,都是用sendEvent发送该对象到js

现象:第一次加入数据的时候,WritableArray的size=1,第二次加入一条数据的时候,WritableArray=0了,起了怪哉

原因:这种对象只能发送一个到js,发送后,该对象会被RN回收掉

方案:还是老老实实在最终发送的时候在组建一个WritableArray对象

14.ListView需要拉一下才显示内容的问题

办法:

removeClippedSubviews={false}

https://github.com/facebook/react-native/issues/1831

15.ListView无法滑动

必须要将renderRow里面的元素通过TouchableXX元素包裹,不然滑动时无法传递手势的

16.this的作用域

场景:在class B类外生命一个const的方法A,在B中使用该方法A  <A  onPress={this.onPress}/>

onPress方法在B类中,有调用this,下面的两种方式截然不同

onPress()
{
      const {XX} = this.state;  //state获取到的是空
}

onPress=()=>{
     const {XX} = this.state;  //state获取到的不为空
}

17.返回并传值到上一个页面

navigator.push(
       component:AA,
       params:{
               onNavigateBack:this.onNavigateBack.bind(this)  //必须要绑定this
       }
})


onNavigateBack=()=>{

}

18.字体大小

ios和android都可以设置系统的字体大小,设置后,app的界面很可能会变乱

Text中有一个属性可以控制是否随系统字体缩放

allowFontScaling(该属性在0.40之前的版本只支持ios,0.40后双平台都支持)

该属性默认是true,设为false后,系统字体的变化不会影响到app,但是不可能所有引用Text组件的地方都去设置一遍吧,有三种方法:

1.自己将Text组件封装一遍,然后将该值设为false

2.在node_modules里面找到react-native的代码,将react-native/Libraries/Text/Text.js中的

getDefaultProps(): Object {
    return {
      accessible: true,
      allowFontScaling: true,  //改为true
      ellipsizeMode: 'tail',
    };
  },

缺点:如果重新npm install的话,都要改该属性,很容易忘记

3.(推荐)直接在入口文件里面设置Text的默认属性

import {
    View,
    Text,
} from 'react-native';


constructor(props) {
        super(props)
        Text.defaultProps.allowFontScaling=false;
    }

具体讨论:https://github.com/facebook/react-native/issues/2519

19.如何获取一个组件的x y width height

<View
                ref="Marker"
                onLayout={({nativeEvent}) => {
                  this.refs.Marker.measure((x, y, width, height, pageX, pageY) => {
                    console.log(x, y, width, height, pageX, pageY);
                  })
                }}
              >

或者

class MainComponent extends Component {
  componentDidMount() {
    // https://github.com/facebook/react-native/issues/953
    setTimeout(this.measureMainComponent);
  }
  measureMainComponent() {
    this.refs.rootView.measure((ox, oy, width, height) => {
      this.setState({rootViewHeight: height});
    });
  }
  render() {
    return (
      <View ref='rootView'/>
    );
  }
}

具体:

https://github.com/facebook/react-native/issues/1374

https://github.com/facebook/react-native/issues/953

20.console性能优化

在release模式下,console的存在对性能是会有影响的,目前有两种做法:

1).在app初始化的时候将这些方法都变成空

if (process.env.NODE_ENV !== 'development') {
    global.console = {
        info: () => {},
        log: () => {},
        warn: () => {},
        error: () => {},
    };
    global.alert = () => {}
}

2).使用babel-plugin-transform-remove-console插件

21.如何使用decorators

npm i --save-dev babel-plugin-transform-decorators-legacy
在.babelrc添加
{
  "presets": [
    "react-native"
  ],
  "plugins": [
    "transform-decorators-legacy"
  ]
}

22.点击两次才能触发onPress

该问题存在与按钮和TextInput同时存在与一个ScrollView中,ScrollView默认的行为是隐藏键盘,然后响应其它事件

#12784   设置keyboardShouldPersistTaps属性为always,然后自己控制键盘的隐藏即可

原文地址:https://www.cnblogs.com/yz1311/p/5737418.html