[新手提问前先来这里看看]React Native的常见问题


  • administrators

    本文主要收集在React Native(以下简称RN)的编译/运行/开发中的常见问题与参考解决方案。

    推荐新手们先看一下环境搭建的视频教程

    从0.25开始,import的方式有所变化,请参考此贴学习 http://bbs.reactnative.cn/topic/981
    从0.18开始,RN默认项目全面转向ES6,语法大变化,请参考此贴学习 http://bbs.reactnative.cn/topic/15

    欢迎加入QQ讨论
    1群439022088(已满),
    2群488376556(已满),
    3群527104912(已满),
    4群 170754112(已满) ,
    5群138811944(已满),
    6群446548027(已满),
    7群115487854(已满),
    8群317323710(已满),
    9群128731649

    这几个群同时讨论RN和react.js

    一般问题

    Q:RN和React.js是一个东西吗?

    A:RN和React.js共用一些抽象层,但具体有很多差异,且目标平台不同:RN目前只能开发iOS/Android App,而React.js用于开发web页面。


    Q:RN有哪些已经上架的案例?

    A:官方有一个showcase页面。我们也收集了一些国内的案例。如果你有作品想要推广,欢迎给我私信。


    Q:RN可以在windows下开发吗?

    A:对于iOS开发,可以通过虚拟机或黑苹果等方式,但很麻烦也不推荐。做iOS开发,迟早你都需要一台Mac电脑。

    对于Android开发,理论上没问题。但由于FB的员工基本都用mac,没有怎么管过windows兼容性,所以目前的版本可能在windows上会遇到一些问题。

    具体搭建方法请参考官方文档以及@天地之灵 总结的完整的windows环境搭建指南


    Q:RN所支持的最低iOS和Android版本?

    A:Android >= 4.1 (API 16)

    iOS >= 7.0


    Q:RN和cordova/phonegap是一个东西吗?

    A:不一样。RN不是一个webview(但包含了webview组件),不能直接复用web页面代码。RN的性能接近原生,超过cordova/phonegap。


    Q:可以使用现有的js库吗?

    A:由于RN理论上更接近nodejs的运行环境,所以对nodejs的库兼容更好一些。浏览器端的js库,涉及到DOM、BOM、CSS等功能的模块无法使用,因为RN的环境中没有这些东西。


    Q:可以使用现有的objc/swift/java库吗?

    A:可以,但需要参照这篇文档这篇文档进行修改。


    Q:可以热更新吗?苹果允许吗?

    A:官方没有提供热更新方案,但本站推出了完整的热更新方案,差异更新只需极小流量。苹果目前的政策明确允许基于javascriptCore的热更新。


    环境搭建与编译问题

    Q:创建新项目,react-native init AwesomeProject命令长时间无响应,或报错shasum check failed

    A:由于众所周知的网络原因,react-native命令行从npm官方源拖代码时会遇上麻烦。请将npm仓库源替换为国内镜像:

    npm config set registry https://registry.npm.taobao.org --global
    npm config set disturl https://npm.taobao.org/dist --global
    

    另,执行init时切记不要在前面加上sudo(否则新项目的目录所有者会变为root而不是当前用户,导致一系列权限问题,请使用chown修复)。


    Q:运行react-native run-android时报错,报错信息中含有Could not find tools.jar等字样

    A:重装JDK1.8


    Q:运行react-native run-android时报错,报错信息中含有SDK location...ANDROID_HOME等字样

    A:请对照官方文档,配置ANDROID_HOME环境变量。


    Q:运行react-native run-android时报错,报错信息中含有bintray.comgradle.org等网址

    A:请(强力)科学上网,反复再反复地重试。


    Q:运行react-native run-android时报错,报错信息中含有not found:gitandroid-23Build Tools revision x.x.xappcompat-v7等字样

    A:请对照官方文档以及@天地之灵 总结的完整的windows环境搭建指南仔细检查漏装的依赖项!(没错,再说一遍,要装全文档里提到的东西,,以及选择对应的版本号!)。


    Q:运行react-native run-android时报错,报错信息中含有No connected devices!字样

    A:既然是没有connected devices,那你就connect一个device咯!(usb连上真机,或启动一个模拟器)。


    Q:运行react-native run-android时报错,报错信息中含有Unable to upload some APKs!字样

    A:参照下图降级gradle版本

    0_1459218230837_QQ图片20160329102338.png


    Q:真机上运行时白屏!

    A:请找到并打开悬浮窗权限。比如miui系统在这里打开悬浮窗权限。


    Q:如何升级RN版本?

    A:请用编辑器打开项目目录中的package.json,找到类似下面的一行配置

    "react-native": "0.13.0",
    将其改为要升级的版本号,如“0.15.0-rc”(当然要先确定这个版本已经发布到npm上了,如果配置中有^或~之类的符号,可以参考这篇文章来了解其含义。)。

    然后在当前目录的命令行中执行npm i

    如果提示权限错误则在前面加上sudo(windows下不需要).

    npm i执行完毕且成功不报错之后,在项目目录中运行(注意这一步会覆盖原生代码,请事先备份原生代码,事后做比对)

    react-native upgrade
    

    对于0.14以下版本升级0.14的情况,还需要额外手动处理一下。


    Q:报错:SyntaxError: Use of const in strict mode

    A:请检查node版本(4.0以上)。


    Q:Windows下报错:ERROR Watcher took too long to load

    Try running watchman version from your terminal

    A:请参照此文底部的说法修改。


    Q:报错:Invariant Violation:Application XXXX has not been registered.

    A:请确保index.*.js中的

    AppRegistry.registerComponent('项目名',() => ...);
    

    与appDelegate.m中的

    RCTRootView*rootView = [[RCTRootViewalloc]initWithBundleURL:jsCodeLocation
    moduleName:@"项目名" launchOptions:launchOptions];
    

    或是MainActivity.java中的

    @Override
    protected String getMainComponentName() {
      return "项目名";
    }
    

    都保持一致。


    Q:应该使用什么IDE开发?

    A:@tdzl2003: 有几个选择:

    1. WebStorm,需要付费购买(学生党可凭edu邮箱在此申请免费授权),最新版对JSX、flowtype等语法支持均非常优秀。
    2. Sublime,虽然会不断提示你是否要购买,然而根据用户协议可以无限期试用。插件系统非常强大,因此如果愿意折腾的话,是个非常不错的选择。
    3. VS Code,微软出的开源跨平台编辑器,适用于编写web代码,也可以用于编写ReactNative项目。据说最近刚刚加入了对JSX的支持(也可能是插件?),整体上相当不错。
    4. nuclide(网页国内无法打开),facebook发布的基于atom的IDE,据说非常不流畅。

    另外虽然主要的业务逻辑是使用js开发,但仍然要依赖于原生的编译/调试环境,所以你还需要同时运行Xcode(iOS)或Android Studio(android)等。


    开发与调试问题

    Q:如何开启调试功能?

    A:点击iOS模拟器顶部的Hardware菜单,选择Shake Gesture(对应真机摇一摇),会自动弹出如下图的菜单。
    0_1450967966242_826615-967fd84e771b47f2.png
    安卓模拟器则是点击菜单键(对于不同的模拟器,其对应键位不同,实在不知道的,可以在命令行中运行adb shell input keyevent 82来触发),真机上没有菜单键的,摇一摇即可。

    选择Debug in Chrome即会启动Chrome作为运行和调试环境(注意此时JS引擎为Chrome的V8,与iOS真机的javascriptCore引擎存在一些差异)。选择Inspect Element即可以像调试网页元素一样查看布局元素的样式,但比较简陋。React Devtools插件可装可不装,它只用来查看布局,不影响调试,且在目前的版本(>0.13)中还无法正常加载
    调试的相关文档点此


    Q:调试模式下报错:Runtime is not ready. Make sure...或是socket closed.

    A:有时Chrome进程会失去响应,可以尝试手动将Chrome的React Native Debugger标签切换到前台再Reload模拟器页面。


    Q:iOS模拟器突然变成了慢动作?

    A:iOS模拟器有个slow animation的选项,其快捷键是commant + T,调试过程中容易误碰到。再按一次关闭这个选项即可。


    Q:使用ListView时报错:Sticky header index 0 was outside the range {...}

    A:看起来是个数组越界错误,但多数情况下是由于ListView的子组件渲染错误(如套数据时没有检查undefined等)引起,而非ListView本身的问题。


    Q:ListView的数据到底应该怎么配?

    A:参考下图
    0_1450968223329_826615-0b079d98f74d7d07.png


    Q:使用Image时报错:You are trying to render the global Image variable as a React element. You probably forgot to require Image.

    A:由于React的Image组件和全局的Image对象重名,所以使用Image组件时一定要记得在文件开头正确引入React的Image组件。


    Q:在使用Navigator的同时使用ListView或ScrollView,后两者的头部会多出一些空间。

    A:将automaticallyAdjustContentInsets属性设为{false}.


    Q:有一些示例代码中有奇怪的问号,比如function foo(x:?string),代表什么意思?

    A:这是通过一个名为flow的外部工具为javascript加上强类型检查的功能,不影响编译和运行。直接无视就好


    Q:报错:Adjacent JSX elements must be wrapped in an enclosing tag.

    A:render方法中必须只能包含一个根元素。


    Q:报错:Invariant Violation: onlyChild must be passed a children with exactly one child

    A:一般是Touchable开头的几个组件,如果没有子元素或者指定多个并列子元素都会报错。


    Q:报错:Invariant Violation: Element type is invalid

    A:如果是引入新组件时报的错,据@tdzl2003 解释:
    从ReactNative 0.16起,babel升级到了6.x版本。
    在babel6中,require和export default不能直接配对使用。
    所以,你要么把

    var Hello = require('./components/Hello');
    

    改为

    import Hello from './components'
    

    要么把

    export default React.createClass({
    

    改为

    module.exports = React.createClass({
    

    二者选其一,配对使用。


    Q:如何获取服务器端数据/可以使用Ajax吗?

    A:可以用ajax,以及大部分现有的ajax库,而且不受浏览器跨域限制。官方推荐用更简单的fetch api来替代传统的ajax.但目前还无法在Chrome中直接观测请求的详情。


    Q:如何读写文件?如何调用摄像头?如何调用麦克风?等等

    A:React Native本身只是一个界面库,没有任何额外的能力。对于官方没有提供的组件或API,请自行在js.coachgithub中搜索第三方实现。如果搜不到相关结果,你只能考虑自己用原生代码实现后整合进来。


    Q:如何在原生代码中调用JS方法?

    A:请参阅这篇文档这篇文档还有这篇文档



  • @sunnylqm 说:

    Q:有一些示例代码中有奇怪的问号,比如function foo(x:?string),代表什么意思?

    A:这是通过一个名为flow的外部工具为javascript加上强类型检查的功能,不影响编译和运行。直接无视就好。

    有个示例代码除了问号,后面还多了点东西,多的那个也可以无视么?
    比如在官方示例里面,UIExplorer的createExamplePages.js

    var createExamplePage = function(title: ?string, exampleModule: ExampleModule)
      : ReactClass<any, any, any> {
    }
    

    后面那串 ReactClass<any,any,any> 是什么意思?


  • administrators

    @limars flowtype的规则很多,有兴趣可以自己翻墙去其官网学习。我的选择是无视——对,统统无视。



  • @sunnylqm 总之都是那个外部工具导致的语法,不研究flow就可以无视是吧,明白了,谢谢。



  • 按照上面配ListView的数据运行后报错undefined not an object evaluating this.renderRow.bind,完整代码如下,

    /**
     * Sample React Native App
     * https://github.com/facebook/react-native
     */
    'use strict';
    
    var React = require('react-native');
    
    var {
      AppRegistry,
      TextInput,
      AppRegistry,
      Component,
      StyleSheet,
      Text,
      Image,
      View,
      ListView,
    } = React;
    
    // var MOCKED_MOVIES_DATA = [
    //   {title: 'Title', year: '2016', posters: {thumbnail: 'http://i.imgur.com/UePbdph.jpg'}},
    // ];
    
    var GithubFinder = React.createClass( {
    render() {
      let dataList = {'数据一':[], '数据二':[], '数据三':[]};
      let dataSource = new ListView.DataSource({
        getRowData:(dataBlob, sectionID, rowID) => {
          return dataBlob[sectionID][rowID];
        },
        getSectionHeaderData: (dataBlob, sectionID) => {
          return dataBlob[sectionID];
        },
        rowHasChanged: (row1, row2) => row1 !== row2,
        sectionHeaderHasChanged: (s1, s2) => s1 !== s2,
      })
    
      let sectionIDs = Object.keys(dataList);
      console.log(sectionIDs);
      let rowIDs = sectionIDs.map( sectionID => {
        let count = dataList[sectionID].lenght;
        console.log(count+"1");
        let thisRow = [];
        for(let i = 0; i < count; i++){
          // console.log(dataList[sectionID]);
          thisRow.push(i);
        }
        console.log(thisRow);
        return thisRow;
      });
    
      return (
        <ListView
          automaticallyAdjustContentInsets={false}
          dataSource={ dataSource.cloneWithRowsAndSections(dataList, sectionIDs, rowIDs)}
          removeClippedSubviews={true}
          renderRow={this.renderRow.bind(this)}
          renderSectionHeader={this.renderSectionHeader.bind(this)}
        />
      );
      },
    })
    
    
    // var styles = StyleSheet.create({
    //   container: {
    //     flex: 1,
    //     flexDirection: 'row',
    //     justifyContent: 'center',
    //     alignItems: 'center',
    //     backgroundColor: '#F5FCFF',
    //   },
    //   rightContainer: {
    //     flex: 1,
    //     backgroundColor: '#FFFFFF'
    //   },
    //   title: {
    //     fontSize: 20,
    //     marginBottom: 8,
    //     textAlign: 'center',
    //   },
    //   year: {
    //     textAlign:'center',
    //   },
    //   thumbnail: {
    //     width: 53,
    //     height: 81,
    //   },
    // });
    
    
    AppRegistry.registerComponent('GithubFinder', () => GithubFinder);
    
    

  • administrators

    @bawn 我一没有填数据,二没有写renderRow方法,这都得你看自己的情况写



  • @sunnylqm 谢谢,原来是我太新手了



  • 第一个问题,中文乱码问题,在调试之初中文是不会出现乱码的,可是现在中文已经出现了乱码,不知道怎么处理才好。
    第二个问题,就是ToolbarAndroid的 actions={[{title: 'Settings', icon: require('image!icon_settings')
    show: 'always'}]}的icon数据对应的右边到底是什么格式的图片,连个后缀都没有,我改成了
    require('./images/自己的图片')报错,我干脆就把icon去掉,直接给我不显示了,官方一点说明都没。



  • 请问下,一个用了listview的app,在快速滑动的时候,容易误认为点击了图片,然后进入图片浮层。这个点击事件 js是怎么判断呢,我明明是滑动事件啊



  • @sunnylqm 说:

    Q:创建新项目,react-native init AwesomeProject命令长时间无响应,或报错shasum check failed

    ant 项目 怎么配置RN?



  • 进页面拉一个请求,页面有A、B、C组件,想根据拉下来数据中的某一个字符串是否为空字符串或者某些数据是否为空来判断是否显示组件C,怎么写呢?我尝试了很多写法都是报RowText ”xxx“ must be wrapped in an explicit <Text> component这个错误。。。



  • 这样:
    {this.state.isShow && <View>...</View>}



  • 加载图片样式会崩溃,请问这个是什么原因,js文件也没怎么改动,0_1474255759231_屏幕快照 2016-09-19 上午11.27.38.png
    0_1474255879172_屏幕快照 2016-09-19 上午11.31.06.png



  • @sunnylqm 说:

    115487854
    麻烦您看下我这个问题是什么原因 谢谢
    http://bbs.reactnative.cn/topic/2931/android-webview打不开带端口的url


登录后回复