环境装置
参见官网:
https://reactnative.dev/docs/environment-setup
https://reactnative.cn/docs/environment-setup
Notes:
- 针对依赖Node外围的包,RN没有进行解决,须要借助rn-nodeify解决,e.g. https://github.com/mvayngrib/react-native-crypto
- 针对Java依赖的版本问题,能够借助jetifier主动解决大部分的版本差别
针对Java依赖版本问题,能够通过patch-package打补丁
- 打出的补丁会蕴含很多无用的局部,能够选择性删除
打出的补丁可能二次批改,e.g.https://github.com/browserify/pbkdf2/blob/master/lib/default-encoding.js
- 源码中
global.process && global.process.version
,装置后global.process && global."v16.13.0"
,patches/pbkdf2+3.1.2.patch
须要二次批改
- 源码中
我的项目创立
npx react-native@latest init rnProject
Notes:项目名称只反对驼峰,不反对连字符。
我的项目运行
npm run android
- 往模拟器或真机装置APK:包运行所须要的资源。
- 援用原生依赖,须要从新运行该命令。
--mode=release
长期打包,输入门路android\app\build\outputs\apk\release
npm run start
- 运行
Metro
打包JS代码,启动热更新,在模拟器或真机实时查看改变。 --reset-cache
革除Metro缓存,从新编译JS代码。
革除运行缓存
"./gradlew" clean
- 切换到
android
目录下,在命令行执行该命令,可革除gradle
缓存。
- 切换到
npx react-native start --reset-cache
- 革除Metro缓存,从新编译JS代码
- 利用场景:环境报错、开发者工具呈现问题
页面适配
计划一:
// src/utils/px2dp.jsimport { Dimensions, PixelRatio, StyleSheet } from 'react-native';const windowWidth = Dimensions.get('window').width;const px2dp = function (px) { if (!isNaN(px)) { return (windowWidth / 1080) * px / PixelRatio.get() } else { return 0 }}export default px2dp// entry.jsimport px2dp from '../utils/px2dp';StyleSheet.create({ pageTitle: { fontSize: px2dp(64), lineHeight: px2dp(85), paddingLeft: px2dp(100), paddingRight: px2dp(100), marginTop: px2dp(80), },})
计划二:
import React from 'react';import { SafeAreaView, StatusBar, View, Text, StyleSheet, Dimensions, PixelRatio,} from 'react-native';const {width: layoutWidth, height: layoutHeight} = Dimensions.get('window');const pixelWidth = PixelRatio.getPixelSizeForLayoutSize(layoutWidth);const pixelHeight = PixelRatio.getPixelSizeForLayoutSize(layoutHeight);const ratio = PixelRatio.get();const styles = StyleSheet.create({ page: { width: pixelWidth, height: pixelHeight, transform: [ { translateX: -0.5 * pixelWidth, }, { translateY: -0.5 * pixelHeight, }, { scale: 1080 / (ratio * pixelWidth), }, { translateX: 0.5 * pixelWidth, }, { translateY: 0.5 * pixelHeight, }, ], }, container: { width: 1080, backgroundColor: 'red', }, half: { width: 540, backgroundColor: 'green', }, quartar: { width: 270, backgroundColor: 'gray', },});function App(): JSX.Element { return ( <SafeAreaView style={styles.page}> <StatusBar barStyle="light-content" /> <View style={styles.container}> <Text>1</Text> </View> <View style={styles.half}> <Text>2</Text> </View> <View style={styles.quartar}> <Text>3</Text> </View> </SafeAreaView> );}export default App;
构造&款式
原生组件:
https://reactnative.dev/docs/components-and-apis
只有特定的组件才有交互款式与事件,如
Button
、TouchableHighlight
、TouchableOpacity
,其余组件无奈绑定onPress
事件- 个别不选用
Button
,而应用自定义Button组件,因为原生Button
款式不好调节
- 个别不选用
- 不反对svg,须要借助第三方库,e.g.
react-native-svg
和react-native-svg-transformer
- 构造搭建:将HTML的标签用法齐全遗记,从新依据文档学习应用办法。
款式:
https://reactnative.dev/docs/image-style-props
- 只能应用组件标准的款式,否则不起作用
lineHeight
不能使文字居中,请应用justifyContent
- 针对
Text
组件,须要独自定义相干款式,不会继承父级非Text
组件Text
款式,e.g.不会从父级继承color
- 不反对渐变色、投影等成果,须要借助第三方库,e.g.
react-native-linear-gradient
、react-native-shadow-2
Notes:第三方库的装置,须要重新启动我的项目,否则,会报模块找不到。
嵌套ScrollView
flatlist
嵌套在scrollView
无奈滚动,父子级都须要设置nestedScrollEnabled属性scrollView
必须设定一个高度,否则会应用默认高度,并非由内容撑开。- 留神
style
与contentContainerStyle
的区别 scrollView
高度设定:专设View
组件包裹,scrollView
高度设置为flex:1
- 留神
代码调试
react-native-debugger的应用
连贯
react-native-debugger
,须要应用程序开启Debug模式- 真机:摇一摇手机,呈现操作面板,抉择
Debug
- 真机:摇一摇手机,呈现操作面板,抉择
模拟器:模拟器聚焦后,应用
Ctrl + m
关上操作面板- 双击
r
是reload
- 双击
应用
react-native-debugger
时,如果收回网络申请,可能会在Network
面板发现没有request
发动,申请(胜利/失败)回调没有执行。在
react-native-debugger
非Chrome控制台面板中右键,开启Enable Network Inspect
- 应用
react-native-debugger
时,如果发现Components
面板始终空白,应用npx react-native start --reset-cache
革除缓存启动我的项目 react-native-debugger
的应用,须要同版本的react-devtools
和react-devtools-core
作为开发依赖。
以后实例获取
类同Chrome开发者工具,在RN任意调试工具的Console面板:
- 通过
$reactNative
等同于import $reactNative from "react-native"
,能够应用react-native
库中的办法。
- 通过
$r
能够获取以后选中节点实例
多种调试工具切换
在模拟器中开启debug
后,调试每次都会主动默认关上debugger-ui
页面,如何敞开:
- 在启动我的项目
npm run start
的命令行中应用shift + d
切换到模拟器并关上调试面板,此时点击debug
面板选项不再主动调起debugger-ui
页面。 - 通过勾销选中小勾号来解决它
Maintain Priority
- 防止间接在模拟器中通过
Ctrl + M
唤起面板,抉择debug
,这样会默认调起debugger-ui
UI审查
开启Android Studio
:
- 通过右下角的
Layout Inspector
,抉择模拟器或真机。
- 点击构造,能够查看组件属性
- 能够通过该面板的右上角设置,切换单位。
- 能够通过给组件赋值
testID
、aria-label
,进行组件辨认。
日志查看
开启Android Studio
:
- 通过下方的
logcat
能够设施日志,可用于剖析应用程序解体起因。 - 可进行日志筛选,e.g.
package:com.awesomeproject level:error
内部字体
https://www.jianshu.com/p/6000eb97d53b
- 不像H5一样,针对不同的
font-weight
设置@
`font-face`
@font-face { font-family: "Sans"; font-weight: 100; src: url("../assets/fonts/Thin.otf");}@font-face { font-family: "Sans"; font-weight: 200; src: url("../assets/fonts/Light.otf");}@font-face { font-family: "Sans"; font-weight: 400; src: url("../assets/fonts/Normal.otf");}
只能通过字体文件名设置不同的fontFamily
:
// font-weight:100f100: { fontFamily: 'Thin' // 字体文件名}// font-weight:200f200: { fontFamily: 'Light' // 字体文件名}// font-weight:300f300: { fontFamily: 'Normal' // 字体文件名}
动画
toValue
只能定义整型,如果动画须要其余类型的值,须要应用interpolate
- 无奈对svg中的circle应用transform定义动画,只能通过View或其余元素包裹,实现旋转动画
- 如果页面内有大量运算,==
Animated
会被阻塞,因为Animated
是在JS线程运行,而非UI线程(https://stackoverflow.com/questions/56980044/how-to-prevent-setinterval-in-react-native-from-blocking-running-animation)
const animationRef = useRef({ strokeDashoffset: new Animated.Value(240), rotateZ: new Animated.Value(1) }) useEffect(() => { const animationDef = () => { Animated.loop( Animated.sequence([ Animated.parallel([ Animated.timing( animationRef.current.strokeDashoffset, { toValue: 240, useNativeDriver: true, duration: 900 } ), Animated.timing( animationRef.current.rotateZ, { toValue: 2, useNativeDriver: true, duration: 900 } ), ]), Animated.parallel([ Animated.timing( animationRef.current.strokeDashoffset, { toValue: 200, useNativeDriver: true, duration: 100 } ), Animated.timing( animationRef.current.rotateZ, { toValue: 3, useNativeDriver: true, duration: 100 } ), ]), Animated.parallel([ Animated.timing( animationRef.current.strokeDashoffset, { toValue: 200, useNativeDriver: true, duration: 900 } ), Animated.timing( animationRef.current.rotateZ, { toValue: 4, useNativeDriver: true, duration: 900 } ), ]), Animated.parallel([ Animated.timing( animationRef.current.strokeDashoffset, { toValue: 240, useNativeDriver: true, duration: 100 } ), Animated.timing( animationRef.current.rotateZ, { toValue: 5, useNativeDriver: true, duration: 100 } ), ]) ]) ).start() } animationDef() }, [animationRef]) const rotateZ = animationRef.current.rotateZ.interpolate({ inputRange: [1, 2, 3, 4, 5], outputRange: ['-100deg', '-424deg', '-500deg', '-784deg', '-820deg'], })
罕用第三方库
我的项目须要重启才能够,否则会报模块找不到
渐变色
import LinearGradient from 'react-native-linear-gradient';
反对svg
"react-native-svg": "^13.9.0",
"react-native-svg-transformer": "^1.0.0",
- 全局款式变量
"react-native-extended-stylesheet": "^0.12.0",
- 毛玻璃
@react-native-community/blur
—— 只能有一个子节点,多个子节点须要包裹
- 投影
yarn add react-native-shadow-2
—— 包裹惟一子节点不能应用margin,会导致Shadow不对齐,如果须要设置margin,应用View包裹Shadow元素
第三方库应用带来的问题
UseEffect vs. UseFocusEffect
应用react-native-navigation
在同一路由栈中切换页面,页面没有销毁,所以,useEffect
的革除回调不会被触发,须要思考应用[useFocusEffect](https://reactnavigation.org/docs/bottom-tab-navigator)
代替useEffect
。
环境变量设置
应用react-native-dotenv
或其余第三方库设置环境变量,会呈现报错:Property left of AssignmentExpression expected node to be of a type ["LVal"] but instead got "StringLiteral"
。
须要批改rn-nodeify
主动生成的shim.js
文件,给process.env
换一种赋值形式:
const isDev = typeof __DEV__ === 'boolean' && __DEV__const env = process.env || {}env['NODE_ENV'] = isDev ? 'development' : 'production'process.env = envif (typeof localStorage !== 'undefined') { localStorage.debug = isDev ? '*' : ''}
报错:ReferenceError: Property 'TextEncoder' doesn't exist, js engine: hermes
https://github.com/hapijs/joi/issues/2141
android.support.annotation包不存在的谬误
jetifier
可一键解决
- 谬误产生在你将你的Android应用程序迁徙到应用
androidx
库时 import
当你应用androidx
,你须要更新你的Android源代码,用androidx.annotation
包替换所有android.support.annotation
包的语句。
https://www.qiniu.com/qfans/qnso-40380519【举荐】
疑难杂症
- 如何同时运行模拟器和真机how to run react-native app on simulator and real device at the same time
https://stackoverflow.com/questions/51336123/how-can-i-run-two-react-native-applications