React-Native学习笔记
起步注意
- 不要使用别人的demo code做练习,因为react-native更新很快,第三方插件更新也很快,如果你使用的是最新版本,别人代码嵌入你自己的demo将举步维艰。
- 基础看完重点放在官方插件上。
- react-navigation重点:一般搭建app基础工程,app肯定需要导航,路由等,官方推荐react-navigation。注意线上中文相关文档帖子大部分都是3.*之前的版本,按其安装会报一些错,下面碰到的几个列一下。
常规错误
Failed to load bundle(http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false) with error:(Unable to resolve module `react-native-gesture-handler` from `/Users/apple/Code/04-IOS/pixeleye/node_modules/@react-navigation/native/src/Scrollables.js`: Module `react-native-gesture-handler` does not exist in the Haste module map
This might be related to https://github.com/facebook/react-native/issues/4968
To resolve try the following:
1. Clear watchman watches: `watchman watch-del-all`.
2. Delete the `node_modules` folder: `rm -rf node_modules && npm install`.
3. Reset Metro Bundler cache: `rm -rf /tmp/metro-bundler-cache-*` or `npm start -- --reset-cache`.
4. Remove haste cache: `rm -rf /tmp/haste-map-react-native-packager-*`. (null))
__38-[RCTCxxBridge loadSource:onProgress:]_block_invoke.228
RCTCxxBridge.mm:414
___ZL36attemptAsynchronousLoadOfBundleAtURLP5NSURLU13block_pointerFvP18RCTLoadingProgressEU13block_pointerFvP7NSErrorP9RCTSourceE_block_invoke.118
__80-[RCTMultipartDataTask URLSession:streamTask:didBecomeInputStream:outputStream:]_block_invoke
-[RCTMultipartStreamReader emitChunk:headers:callback:done:]
-[RCTMultipartStreamReader readAllPartsWithCompletionCallback:progressCallback:]
-[RCTMultipartDataTask URLSession:streamTask:didBecomeInputStream:outputStream:]
__88-[NSURLSession delegate_streamTask:didBecomeInputStream:outputStream:completionHandler:]_block_invoke
__NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__
-[NSBlockOperation main]
-[__NSOperationInternal _start:]
__NSOQSchedule_f
_dispatch_call_block_and_release
_dispatch_client_callout
_dispatch_continuation_pop
_dispatch_async_redirect_invoke
_dispatch_root_queue_drain
_dispatch_worker_thread2
_pthread_wqthread
start_wqthread
如果是react-navigation相关的,原因是没有安装react-native-gesture-handler,安装即可。
npm install --save react-native-gesture-handler
重新编译。
Unhandled JS Exception: undefined is not an object (evaluating '_react.default.PropTypes.string')
RCTFatal
-[RCTExceptionsManager reportFatalException:stack:exceptionId:]
__invoking___
-[NSInvocation invoke]
-[NSInvocation invokeWithTarget:]
-[RCTModuleMethod invokeWithBridge:module:arguments:]
facebook::react::invokeInner(RCTBridge*, RCTModuleData*, unsigned int, folly::dynamic const&)
facebook::react::RCTNativeModule::invoke(unsigned int, folly::dynamic&&, int)::$_0::operator()() const
invocation function for block in facebook::react::RCTNativeModule::invoke(unsigned int, folly::dynamic&&, int)
_dispatch_call_block_and_release
_dispatch_client_callout
_dispatch_lane_serial_drain
_dispatch_lane_invoke
_dispatch_workloop_worker_thread
_pthread_wqthread
start_wqthread
新版本prop-types独立出来,如果使用就接口会找不到,需要安装对应插件。
npm install prop-types --save
react-navigation注意事项
- 避免导航器内部的screen在渲染另一个导航器。 参考https://reactnavigation.org/docs/en/common-mistakes.html说明。如果确实需要这么使用在组件标签内需要添加navigation={this.props.navigation}。
- 如果将AppContainer包装在View中,请确保View正在使用flex。这个不知道什么原理,贴出demo。
import React from 'react';
import { Text, View } from 'react-native';
import { createBottomTabNavigator, createAppContainer } from 'react-navigation';
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
</View>
);
}
}
class SettingsScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
</View>
);
}
}
const TabNavigator = createBottomTabNavigator({
Home: HomeScreen,
Settings: SettingsScreen,
});
const AppContainer = createAppContainer(TabNavigator);
// without the style you will see a blank screen
export default () =><View style={{flex: 1}}><AppContainer/></View>;
- react-navigation@2.14.0之前是all screens are essentially regular native View in each platform所以增加了内存的消耗 (官方原话就不翻译了,不知道platform指的是什么,是android/ios还是手机)。
- react-navigation的动态路由:官方不推荐使用动态路由,React Navigation目前在静态定义路由的情况下效果最佳的。如果真的需要动态路由参考https://reactnavigation.org/docs/en/params.html 。
- React-navigation在3D触控设备上不支持peek & pop功能。
- 注意:官方文档
import Ionicons from 'react-native-vector-icons/Ionicons';
替换成import Icon from 'react-native-vector-icons/Ionicons';
。 - 高阶组件:withNavigation是一个高阶组件,它可以将navigation这个prop传递到一个包装的组件。 当你无法直接将navigation这个prop传递给组件,或者不想在深度嵌套的子组件中传递它时,它将非常有用。
- 屏幕进入或者推出时出发函数(比如比如停止播放视频或音频文件,或停止跟踪用户的位置。)
- 使用react-navigation提供的withNavigationFocus高阶组件。
- 使用事件监听器收听'didFocus'事件。 参考https://reactnavigation.org/docs/zh-Hans/function-after-focusing-screen.html
其他插件
React-native开发-Unrecognized font family ‘Ionicons’ 解决:https://blog.csdn.net/zhaolaoda2012/article/details/82627735 新版本的Ionicons已经替换为Icon。
import Icon from 'react-native-vector-icons/Ionicons';
评论