本文今后将只在 ReactNative中文网 进行更新,此处不再维护,请点击这里移步。
本文主要收集在React Native(以下简称RN)的编译/运行/开发中的常见问题与参考解决方案,并非完整教程。
本文最后更新时间2016年1月19日,对应rn版本0.18
0.18正式版有一个bug,导致无论在win还是mac下新建的项目都无法正常运行,请参阅此贴解决
从0.18开始,RN默认项目全面转向ES6,语法大变化,请参考此贴学习http://bbs.reactnative.cn/topic/15
欢迎加入QQ讨论群439022088,本群同时讨论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库吗?
环境搭建与编译问题
Q:创建新项目,react native init xxx命令长时间无响应,或报错shasum check failed
A:由于众所周知的网络原因,react-native命令行从npm官方源拖代码时会遇上麻烦。请将npm仓库源替换为国内镜像:
npm config set registry https://registry.npm.taobao.org
npm config set disturl https://npm.taobao.org/dist
另,执行init时切记不要在前面加上sudo(否则新项目的目录所有者会变为root而不是当前用户,导致一系列权限问题,请使用chown修复)。
11月1日更新:react-native.cn中文网提供了完整的绿色纯净新项目包。完整打包全部iOS和Android的第三方依赖,只要环境配置正确,无需科学上网漫长等待,即可直接运行。
Q:报错EACCES: permission denied, open 'Users/你的用户名/.babel.json'
A:执行如下命令:
sudo chown 你的用户名 ~/.babel.json
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:报错:EMFILE, too many open files '......'
A:请检查node版本(4.0以上),以及是否安装了watchman(目前只有Mac能装这个)
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.ios.js中的
AppRegistry.registerComponent('项目名',() => ...);
与appDelegate.m中的
RCTRootView*rootView = [[RCTRootViewalloc]initWithBundleURL:jsCodeLocation
moduleName:@"项目名" launchOptions:launchOptions];
或是MainActivity.java中的
mReactRootView.startReactApplication(mReactInstanceManager, "项目名", null);
都保持一致。
Q:应该使用什么IDE开发?
A:虽然常用的JS编辑器很多,但由于RN大量使用jsx和es6语法,目前只有sublime text(通过插件)和webstorm(10以上版本)提供了良好的支持。笔者推荐webstorm,因为它有更完善的语法提示和补全。另外虽然主要的业务逻辑是使用js开发,但仍然要依赖于原生的编译/调试环境,所以你还需要同时运行Xcode(iOS)或Android Studio(android)等。
开发与调试问题
Q:如何开启调试功能?
A:点击iOS模拟器顶部的Hardware菜单,选择Shake Gesture(对应真机摇一摇),会自动弹出如下图的菜单。
安卓模拟器则是点击菜单键,真机上没有菜单键的,摇一摇即可。
选择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:使用ListView时报错:Sticky header index 0 was outside the range {...}
A:看起来是个数组越界错误,但多数情况下是由于ListView的子组件渲染错误(如套数据时没有检查undefined等)引起,而非ListView本身的问题。
Q:ListView的数据到底应该怎么配?
A:参考下图
Q:require静态图片时报找不到模块的错误
A:参看下图步骤,尤其需要注意的点是文件名必须和imageset的名字一致。(注:这里演示的是0.14之前版本的添加图片的步骤。0.14之后的图片用法点这里)
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:如何获取服务器端数据/可以使用Ajax吗?
A:可以用ajax,以及大部分现有的ajax库,而且不受浏览器跨域限制。官方推荐用更简单的fetch api来替代传统的ajax.但目前还无法在Chrome中直接观测请求的详情。
Q:如何读写文件?如何调用摄像头?如何调用麦克风?等等
A:对于官方没有提供的组件或API,请自行在react.parts或github中搜索第三方实现。如果搜不到相关结果,你只能考虑自己用原生代码实现后整合进来。
Q:如何在原生代码中调用JS方法?
A:请参阅官网中Native Modules一节文档,其中提供了回调Callbacks和监听事件两种方法,且都为异步。
//To be continued
网友评论
The following commands produced analyzer issues:
Analyze /Users/qiangzi/Downloads/ReactStart/170106/ReactNativeDemo/node_modules/react-native/ReactCommon/yoga/yoga/YGNodeList.c
Analyze /Users/qiangzi/Downloads/ReactStart/170106/ReactNativeDemo/node_modules/react-native/ReactCommon/yoga/yoga/Yoga.c
(2 commands with analyzer issues)
The following build commands failed:
CompileC /Users/qiangzi/Downloads/ReactStart/170106/ReactNativeDemo/ios/build/Build/Intermediates/React.build/Debug-iphonesimulator/yoga.build/Objects-normal/x86_64/Yoga.o /Users/qiangzi/Downloads/ReactStart/170106/ReactNativeDemo/node_modules/react-native/ReactCommon/yoga/yoga/Yoga.c normal x86_64 c com.apple.compilers.llvm.clang.1_0.compiler
Analyze /Users/qiangzi/Downloads/ReactStart/170106/ReactNativeDemo/node_modules/react-native/ReactCommon/yoga/yoga/YGNodeList.c
Analyze /Users/qiangzi/Downloads/ReactStart/170106/ReactNativeDemo/node_modules/react-native/ReactCommon/yoga/yoga/Yoga.c
(3 failures)
找不到packager.js了