当前项目 react-native 版本 "0.64.0",
坑位
exclude 'classes.dex' exclude '**.**'
stackoverflow.com/questions/6…
待审查 挨个问好? blog.csdn.net/IT_fighter/…
Direct local .aar file dependencies are not supported when building an AAR
问题 出现在支付宝支付的库上
developer.android.com/studio/buil…
opensupport.alipay.com/support/fee…
stackoverflow.com/questions/6…
---最后发现一个 issue
- ./gradlew assembleRelease
+ ./gradlew :app:assembleRelease
stackoverflow.com/questions/6…
android 开启
Hermes
打包过程会出现各种 waring
例如等诸多 warning
the variable "requestAnimationFrame" was not declared in function
hermesFlagsRelease: ["-w"]
react-native-wechat-lib 使用的
androidx.annotation
导致其他项目android.support.annotation
炸裂
只能快捷操作 Ctrl + Shift + R
全局替换androidx.annotation
github.com/facebook/re… 等等问题 issue
解决方案
cd android && ./gradlew clean : 如果使用androidStudio打包则不需要
yarn add jetifier
npx jetify
就可以了
避免俩套高德 key 或者微信 appid
android/app/build.gradle
release 和 debug 指定同一个
signingConfigs {
debug {
storeFile file('app.keystore')
storePassword '...'
keyAlias '...'
keyPassword '...'
}
release {
storeFile file('app.keystore')
storePassword '...'
keyAlias '...'
keyPassword '...'
}
}
buildTypes {
release {
// Caution! In production, you need to generate your own keystore file.
// see https://reactnative.dev/docs/signed-apk-android.
signingConfig signingConfigs.release
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
debug {
signingConfig signingConfigs.debug
}
}
android 开启了 打包正式报错
java.lang.outofmemoryerror
stackoverflow.com/questions/5…
Task :app:packageRelease FAILED
+FAILURE: Build completed with 2 failures
+1: Task failed with an exception
可以尝试清除缓存
cd ./android && ./gradlew clean
D8: java.lang.OutOfMemoryError: Java heap space
Task orphaned for request <NSMutableURLRequest...
ios textinput bug 拼音会限制到 maxlength 上
www.dazhuanlan.com/2019/10/14/…
虚线的问题 android
禁用系统字体
不随系统的显示大小
DispUtility.java
package com.gunner;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.view.Display;
import java.lang.reflect.Method;
/**
* Author : monkey0928
* E-mail : hanbao@xwtec.c
* Date : 2020/6/29 17:54
* DESCRIBE :禁用 7.0(23)以上字体大小和显示大小随系统变化
*/
public final class DispUtility {
/**
* 禁用7.0(23)以上显示大小改变和文字大小
*/
public static Resources disabledDisplayDpiChange(Resources res) {
Configuration newConfig = res.getConfiguration();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//字体非默认值
if (res.getConfiguration().fontScale != 1) {
newConfig.fontScale = 1;
}
newConfig.densityDpi = getDefaultDisplayDensity();
res.updateConfiguration(newConfig, res.getDisplayMetrics());
} else {
//字体非默认值
if (res.getConfiguration().fontScale != 1) {
newConfig.fontScale = 1;//设置默认
res.updateConfiguration(newConfig, res.getDisplayMetrics());
}
}
return res;
}
/**
* 获取手机出厂时默认的densityDpi
*/
public static int getDefaultDisplayDensity() {
try {
Class aClass = Class.forName("android.view.WindowManagerGlobal");
Method method = aClass.getMethod("getWindowManagerService");
method.setAccessible(true);
Object iwm = method.invoke(aClass);
Method getInitialDisplayDensity = iwm.getClass().getMethod("getInitialDisplayDensity", int.class);
getInitialDisplayDensity.setAccessible(true);
Object densityDpi = getInitialDisplayDensity.invoke(iwm, Display.DEFAULT_DISPLAY);
return (int) densityDpi;
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
}
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
+ DispUtility.disabledDisplayDpiChange(this.getResources());
}
ios http 请求 的
info.plist
App Transport Security Settings 需要一个Allow Arbitrary Loads
e.g
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
<key>https://restapi.amap.com/v3</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
pod install --verbose 可以查看进度
pod install 卡在 Flipper 或者 'event2/event-config.h' file not found
(答案来源于)[stackoverflow.com/questions/6…]
pod install 卡在 Flipper 是自身遇到,修改直接成功了 2021/3/19 --下载显示的版本是 0.75.1--实在是 pod 不下来,总结下来就是指定版本
ios/Podfile
修改
- use_flipper!()
+ use_flipper!({ 'Flipper' => '0.74.0' })
ios
run
需要有team
账号--没有的需要注册
位置:XCode
选中项目>TARGETS
>Signing&Capabilities
>Signing
axios 的问题 android9 以上不支持 http ios 不支持 http
AndroidManifest.xml
<!-- https://github.com/axios/axios/issues/973 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Info.plist
加上这俩段
<key>NSAppTransportSecurity</key>
<dict>
+ <key>NSAllowsArbitraryLoads</key>
+ <true/>
</dict>
禁止首页 tanbar 存在的页面因为键盘把 tabbar 顶上去
<activity
android:name=".MainActivity"
+ android:windowSoftInputMode="adjustPan"
goBack() 回调传参
禁止旋转
android
<activity
android:name=".MainActivity"
+ android:screenOrientation="portrait"
ios
位置:XCode
选中项目>TARGETS
>General
>Deployment Info
>Device Orientation
Bundle Identifier
不能够重复
只选中第一个就好
在同一台电脑不能同时执行 run IOS 和 Android
比如 IOS 用 Xcode RUN 了一个到 IOS 虚拟机上,然后直接敲命令yarn run android
会被 Connection refused: connect
MAC
装 adb
brew install android-platform-tools
You need the android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag
报错
小米手机需要开启USB调试(安全设置)
全局范围的扩大仅可直接嵌套在外部模块中或环境模块声明中
declare global {
interface String {
hump(input: string): string;
}
}
// 注意: 修改"全局声明"必须在模块内部, 所以至少要有 export{}字样
// 不然会报错❌: 全局范围的扩大仅可直接嵌套在外部模块中或环境模块声明中
export {}
忽略 ts 类型
- 忽略当前文件的
ts
检测
/* eslint-disable */
- 忽略下一行的
ts
检测
// eslint-disable-next-line
- 忽略库的 ts 类型检测
// @ts-ignore
使用别名路径
yarn add --dev babel-plugin-module-resolver
babel.config.js
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
[
'module-resolver',
{
root: ['./src'],
extensions: ['.ios.js', '.android.js', '.js', '.ts', '.tsx', '.json'],
alias: {
'@components': './src/components',
'@pages': './src/pages',
'@type': './src/types',
'@assets': './src/assets',
'@utils': './src/utils',
'@store': './src/store',
'@config': './src/config',
'@api': './src/api'
}
}
],
[
'@babel/plugin-proposal-decorators',
{
legacy: true
}
]
]
}
tsconfig.json
{
+ "baseUrl": ".",
+ "paths": {
+ "@components/*": ["src/components/*"],
+ "@pages/*": ["src/pages/*"],
+ "@type/*": ["src/types/*"],
+ "@assets/*": ["src/assets/*"],
+ "@utils/*": ["src/utils/*"],
+ "@store/*": ["src/store/*"],
+ "@config/*": ["src/config/*"],
+ "@api/*": ["src/api/*"]
+ },
"exclude": [
"node_modules", "babel.config.js", "metro.config.js", "jest.config.js"
]
}
xcode 报错
Command PhaseScriptExecution failed with a nonzero exit code
mac 内存不足的问题
No version of NDK matched the requested version 22.0.7026061. Versions available locally: 23.0.7123448, 23.0.7123448
打开 AndroidStudio>Preferences
>Appearance & Behavior
>System Setting
>Android SDK
tab 选项卡到SDK Tools
,把 NDK 勾选上然后下载
点击右下角 Show Package Details
找到版本 22.0.7026061 下载
VScode
安装 prettier
前提下
.prettierrc
{
"singleQuote": true,
"semi": false,
"tabWidth": 2,
"useTabs": false,
"trailingComma": "none",
"endOfLine": "lf"
}
metro & babel
我们在 TS 配置中涉及到了 metro.config.js、.babelrc、tsconfig 等一系列的配置文件,这里简单总结下他们之间的关系。
metro:是 Facebook 开发的一个专门为 React Native 提供 JS 的 bundler,作用和前端中的 webpack 类似,也有人尝试使用 metro 作为前端的编译打包工具。
metro 通过调用 babel 提供将 ES6、JSX、TS 等编译成 ES5 的 JS 代码。
metro.config.js、.babelrc 则是编译期间需要使用的配置文件,tsconfig 目前更多的是给 VSCode、WebStorm 等开发工具使用做 TS 校验
React Native 0.64
版本
zhuanlan.zhihu.com/p/356940165
iOS开启支持Hermes引擎
-
- 此次版本更新也正是开启了 iOS 平台上支持了 Hermes。开启 Hermes 支持也很简单,在 Podfile 文件中设置 hermes_enabled 为 true,然后在执行 pod install 就可以了。
use_react_native!(
:path => config[:reactNativePath],
# to enable hermes on iOS, change `false` to `true` and then install pods
- :hermes_enabled => false
+ :hermes_enabled => true
)
app/build.gradle
project.ext.react = [
- enableHermes: false, // clean and rebuild if changing
+ enableHermes: true, // clean and rebuild if changing
]
- def enableHermes = project.ext.react.get("enableHermes", false);
+ def enableHermes = project.ext.react.get("enableHermes", true);
hermes_enabled 这个库 483M,会碰到 pod 很慢的情况,最好通过
pod install --verbose
进行观察原因,基本是网慢,最快一百多 K 每秒,是在弄不下来就 false 吧,我勉强拉下来了幸运花了一个多小时
-
- 默认启用 Inline Requires
Inline Requires 是一个 Metro 配置选项,它通过延迟加载 JavaScript 模块的执行,来缩短启动时间,提交加载速度。其作为可选配置选择已经存在很多年,现在新版本应用中默认开启,以此帮助用户无需额外配置就可以快速使用 React Native.
Inline Requires 是一种 Babel 变换,它可以将模块导入并转换为 inline。例如,Inline Requires 将这个模块导入调用从文件的 top 转换到使用它的地方。
- import { MyFunction } from 'my-module';
const MyComponent = (props) => {
- const result = MyFunction();
+ const result = require('my-module').MyFunction();
return (<Text>{result}</Text>);
};
-
- 支持 React 17
e.g: 不需要使用import React from 'react'
就可以使用jsx
- import React from 'react';
function App() {
return <h1>Hello World</h1>;
}
- import React from 'react';
+ import { useState } from 'react';
function App() {
- const [text, setText] = React.useState('Hello World');
+ const [text, setText] = useState('Hello World');
return <h1>{text}</h1>;
}
mac 安卓安装 jdk
android 报错
Direct local .aar file dependencies are not supported when building an AAR
直接用 androidStudio 打而不是用命令。。。。【因为我打出来了,命令就是报这个错误】
android 会出现层级问题【ios 表现正常】
添加样式
elevation:0.001
后来发现可能跟位置有关
textarea[多行的 textarea]
www.react-native.cn/docs/textin…
配置 eslint
- eslint-import-resolver-typescript:和 eslint-import-resolver-webpack 类似,主要是为了解决 alias 的问题
- eslint-plugin-react: React 专用的校验规则插件
- eslint-plugin-jsx-a11y: 该依赖包专注于检查 JSX 元素的可访问性
- eslint-plugin-react-native: React-Native 专用的校验规则插件
- eslint-plugin-import: 该插件想要支持对 ES2015+ (ES6+) import/export 语法的校验, 并防止一些文件路径拼错或者是导入名称错误的情况
- eslint-plugin-promise: promise 规范写法检查插件,附带了一些校验规则
ts 部分
- @typescript-eslint/parser:ESLint 的解析器,用于解析 typescript,从而检查和规范 Typescript 代码
- @typescript-eslint/eslint-plugin:这是一个 ESLint 插件,包含了各类定义好的检测 Typescript 代码的规范
yarn add eslint-plugin-jsx-a11y eslint-plugin-react eslint-plugin-react-native eslint-import-resolver-typescript eslint-plugin-promise eslint-plugin-import @typescript-eslint/parser @typescript-eslint/parser @typescript-eslint/eslint-plugin -D
.eslintrc.js
module.exports = {
root: true,
env: {
es6: true,
browser: true,
node: true,
jest: true,
'react-native/react-native': true
},
plugins: [
// ESLint 支持使用第三方插件。在使用插件之前,你必须使用 npm 安装它。
'react',
'react-native'
],
extends: [
'@react-native-community',
'plugin:react-native/all',
'plugin:@typescript-eslint/recommended'
],
parser: '@typescript-eslint/parser', // 解析器
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module',
ecmaFeatures: {
tsx: true, //允许解析tsx Allows for the parsing of JSX
jsx: true
}
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
/* allow async-await */
'generator-star-spacing': 'off',
'no-empty': 2,
/* 方法名和刮号之间需要有一格空格 --禁用 */
'space-before-function-paren': 0,
'comma-dangle': [2, 'never'],
camelcase: 0,
/* 末尾不需要分号结束 */
semi: 0,
/* 使用单引号 */
quotes: ['error', 'single'],
// 样式排序
'react-native/sort-styles': 0
}
}
禁用掉部分区域的滑动手势
规范提交commit
yarn add commitizen cz-customizable husky@4.3.8 commitlint-config-cz lint-staged cz-conventional-changelog @commitlint/cli @commitlint/config-conventional -D
-
第一位:0 为 disable,1 为 warning,2 为 error
第二位:应用与否,可选 always|never
第三位:rule 的值
type(scope?): subject body? footer? scope 指 commit 的范围(哪些模块进行了修改) subject 指 commit 的简短描述 body 指 commit 主体内容(长描述) footer 指 commit footer 信息
- type-enum:类型在值中找到
- subject-full-stop:
- type-case:类型大小写
- scope-empty:修改范围
- scope-case:scope 值的情况 ....
-
配置 package.json
husky hoosks 根据 commitlint.config.js 配置
lint-staged 里面加 eslint 的 hooks
"scripts":{ "commit": "git-cz" }, "config": { "commitizen": { "path": "cz-customizable" } }, "husky": { "hooks": { "pre-commit": "lint-staged", "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" } }, "lint-staged": { "*.{js,jsx,vue}": [] },
-
.cz-config.js
'use strict'; module.exports = { types: [ { value: 'feat', name: 'feat: 增加新功能' }, { value: 'fix', name: 'fix: 修复bug' }, { value: 'ui', name: 'ui: 更新UI' }, { value: 'refactor', name: 'refactor: 代码重构' }, { value: 'release', name: 'release: 发布' }, { value: 'docs', name: 'docs: 修改文档' }, { value: 'test', name: 'test: 增删测试' }, { value: 'chore', name: 'chore: 更改配置文件' }, { value: 'style', name: 'style: 代码样式修改不影响逻辑' }, { value: 'revert', name: 'revert: 版本回退' }, { value: 'add', name: 'add: 添加依赖' }, { value: 'del', name: 'del: 删除代码/文件' }, { value: 'build', name: 'del: 修改项目构建系统' }, { value: 'perf', name: 'perf: 性能优化' }, { value: 'breaking change', name: 'breaking change: 重大改变' }, { value: 'types', name: 'types: 修改定义文件' } ], scopes: [], messages: { type: '选择更改类型:\n', scope: '请输入更改的范围:\n', // 如果allowcustomscopes为true,则使用 // customScope: 'Denote the SCOPE of this change:', subject: '简短描述:\n', body: '详细描述. 使用"|"换行:\n', breaking: 'Breaking Changes列表:\n', footer: '关闭的issues列表. E.g.: #31, #34:\n', confirmCommit: '确认使用以上信息提交?(y)' }, allowCustomScopes: true, allowBreakingChanges: ["feat", "fix"] };
-
commitlint.config.js
module.exports = { extends: ['@commitlint/config-conventional', "cz"], rules: { 'type-enum': [ 2, 'always', [ "release",/* 腹部 */ "del",/* 删除代码/文件 */ "add",/* 新增依赖 */ "ui",/* 更新UI */ "feat",/* 新增功能 */ "fix",/* 修复bug */ "docs",/* 修改文档 */ "style",/* 代码样式修改不影响逻辑 */ "refactor",/* 代码重构 */ "test",/* 增删测试 */ "chore",/* 更改配置文件 */ "revert",/* 回滚代码 */ "breaking change",/* 重大改变 */ "types",/* 修改定义文件 */ "perf",/* 性能优化 */ "build"/* 修改项目构建工具 */ ] ], 'type-empty': [2, 'never'], 'type-case': [0], 'scope-empty': [0], 'subject-full-stop': [0, 'never'], 'subject-empty': [2, 'never'], /* 提交不符合规范时,也可以提交,但是会有警告 */ 'subject-case': [0, 'never'], 'scope-case': [2, 'always', 'lower-case'], 'header-max-length': [2, 'always', 72], } }
扩展库
react-native-extended-stylesheet
提供了样式的提供的扩展功能
yarn add react-native-extended-stylesheet
index.js
入口文件
import EStyleSheet from 'react-native-extended-stylesheet';
// 你不使用全局变量也需要在入口文件进行build
EStyleSheet.build({
$textColor: '#0275d8'
});
全局变量
// 入口文件
EStyleSheet.build({
$textColor: '#0275d8'
});
// 在组件样式中使用
const styles = EStyleSheet.create({
text: {
color: '$textColor'
}
});
// 作为内联样式或者组件属性使用
<View style = {{
backgroundColor: EStyleSheet.value('$textColor')
}}>
</View>
局部变量
局部变量优先于全局变量,可以覆盖全局变量,局部变量可以直接通过 styles.$textColor 获取数值。
const styles = EStyleSheet.create({
$textColor: '#0275d8',
text: {
color: '$textColor'
},
icon: {
color: styles.$textColor
},
});
媒体查询
// global level
EStyleSheet.build({
'@media ios': {
$fontSize: 12,
},
'@media android': {
$fontSize: 16,
},
});
// sheet level
const styles = EStyleSheet.create({
column: {
width: '80%',
},
'@media (min-width: 350) and (max-width: 500)': {
column: {
width: '90%',
}
}
});
// style level
const styles = EStyleSheet.create({
header: {
'@media ios': {
color: 'green',
},
'@media android': {
color: 'blue',
},
}
});
数值操作
任何的值都可以包含+,-,*,/数值操作,操作数可以是数值,变量,和百分比
const styles = EStyleSheet.create({
$size: 20,
circle: {
width: '$size',
height: '$size',
borderRadius: '0.5 * $size'
}
});
REM 单位
与 CSS3 的 rem unit 允许定义相对于根元素的一个整数值,rem 默认值是 16。依赖屏幕的尺寸或者其他条件可以很容易的去扩展应用。
// component
const styles = EStyleSheet.create({
text: {
fontSize: '1.5rem',
marginHorizontal: '2rem'
}
});
// app entry
let {height, width} = Dimensions.get('window');
EStyleSheet.build({
$rem: width > 340 ? 18 : 16
});
百分比
百分比支持是从 React Native 0.43 开始的。EStyleSheet 通过扩展原有的 StyleSheet 可以使用百分比计算。百分比算通过应用的屏幕去计算。
const styles = EStyleSheet.create({
column: {
width: '100% - 20'
}
});
缩放
通过设置一个特殊变量去缩放(改变组件的 width,height,以及 margin)组件
const styles = EStyleSheet.create({
$scale: 1.5,
button: {
width: 100,
height: 20,
marginLeft: 10
}
});
可以通过传递一个属性去控制组件的尺寸
class Button extends React.Component {
static propTypes = {
scale: React.PropTypes.number
};
render() {
let style = getStyle(this.props.scale)
return (
<View style={style.button}>
</View>
);
}
}
let getStyle = function (scale = 1) {
return EStyleSheet.create({
$scale: scale,
button: {
width: 100,
height: 20,
marginLeft: 10
}
});
}
下拉刷新加载库
借鉴 https://github.com/bozaigao/react-native-refresh-loadmore-recyclerlistview
、https://github.com/bolan9999/react-native-largelist
以及 recyclerlistview
yarn add ts-object-utils
lodash==>[直接把 debounce 从 lodash 源码扣下来] debounce
yarn add @react-native-community/async-storage
cd ios && pod install
视频组件
- react-native-orientation 旋转监听 Q.需要配置
IOS
cd ios && pod install
AppDelegate.m
+ #import "Orientation.h" // <--- import
@implementation AppDelegate
// ...
+ - (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
+ return [Orientation getOrientation];
+ }
@end
ANDROID
MainActivity.java
package com.technicianuser;
+ import android.content.Intent; // <--- import
+ import android.content.res.Configuration; // <--- import
import com.facebook.react.ReactActivity;
public class MainActivity extends ReactActivity {
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "technicianUser";
}
+ /**
+ * 监听App旋转
+ */
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ Intent intent = new Intent("onConfigurationChanged");
+ intent.putExtra("newConfig", newConfig);
+ this.sendBroadcast(intent);
+ }
}
- react-native-slider 滑条 Q.不需要配置
yarn add react-native-video react-native-slider react-native-orientation
IOS
配置
cd ios && pod install
重新编译
ANDROID
配置
gradle.properties
+ android.useAndroidX=true
+ android.enableJetifier=true
图片缓存库
yarn add react-native-fast-image
cd ios && pod install
重新编译安装程序
学习
学习所得
aspectRatio 用法
在保持宽高比的情况下,我们应该尽可能使用 aspectRatio 来实现,比如,有个图片,在 750 设计稿 里量来是 126*134 ,宽度占父级的 50%,我们可以这样来实现:
const style = {
width: '50%',
// **注意**,下面这个 height: undefined 样式,在加载 **本地图片** 时,是必须的!
height: undefined,
aspectRatio: 126 / 134,
};
//later in render
<Image style={style}></Image>
两侧间距固定,中间自适应
const style = {
marginHorizontal: 20,
alignSelf: 'stretch',
};
//render
<View style={style}></View>
渐变组件
yarn add react-native-linear-gradient
cd ios && pod install
重新编译
webview 组件
yarn add react-native-webview
cd ios && pod install
重新编译
Android
- react-native-webview 版本>=6.X。X:请通过编辑 android/gradle 确保你的项目中启用了 AndroidX。属性和添加 2 行:
gradle.properties
默认应该是有的
android.useAndroidX=true
android.enableJetifier=true
删除 console.*
在运行打好了离线包的应用时,控制台大量打印语句可能会拖累 JavaScript 线程。注意有些第三方调试库也可能包含控制台打印语句,比如 redux-logger,所以在发布应用前请务必仔细检查,确保全部移除。
有个 babel 插件可以帮你移除所有的 console.*调用。首先需要使用 yarn add --dev babel-plugin-transform-remove-console 来安装,然后在项目根目录下编辑(或者是新建)一个名为·.babelrc`的文件,在其中加入:
{
"env": {
"production": {
"plugins": ["transform-remove-console"]
}
}
}
HOC 高阶函数 工具
hoist-non-react-statics
使用高阶组件遇到的问题:静态方法丢失 ,当使用高阶组件包裹原始组件,返回的新组件会丢失原始组件的所有静态方法。 使用 hoist-non-react-statics 来帮你自动处理,它会自动拷贝所有非 React 的静态方法;(react-router 里 withRouter 就使用了这个包)
yarn add hoist-non-react-statics
模态框
由于 react-native-modal 是原始 react native 模态的扩展,它以类似的方式工作
react-native-modal
yarn add react-native-modal
android
做到全屏 状态栏不存在
- 方法二
react-native-modal 与 react-native-translucent-modal 结合源码到本地
yarn add react-native-animatable react-native-translucent-modal
- 方法一有点丑 他是一个隐藏
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.ReactNative.AppCompat.Light.NoActionBar.FullScreen">
<!-- Customize your theme here. -->
</style>
<style name="AppTheme.Launcher">
<item name="android:windowBackground">@drawable/launch_screen</item>
</style>
</resources>
图片查看器
---- 可以学习 github.com/indulgeIn/Y…
react-native-image-zoom-viewer
yarn add react-native-image-zoom-viewer
为了做到保存图片功能
@react-native-community/cameraroll
yarn add @react-native-community/cameraroll
cd ios && pod install
报错
Error: Unable to resolve module fbjs/lib/invariant
解决
yarn add fbjs
Android
借助库
rn-fetch-blob
yarn add rn-fetch-blob
虽然ios
不会用到这个库 ,但是还是弄一下好了
cd ios && pod install
从 Android 10 开始,介绍了作用域存储的概念。目前,要使它与改变工作,你必须添加
AndroidManifest.xml
<manifest ... >
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
</manifest>
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
....
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
</intent-filter>
ios
警告
Require cycle: node_modules/rn-fetch-blob/index.js -> node_modules/rn-fetch-blob/polyfill/index.js -> node_modules/rn-fetch-blob/polyfill/Fetch.js -> node_modules/rn-fetch-blob/index.js
解决
github.com/joltup/rn-f… 这个 pr 不合并 哎 自己搞
save 方法
在 Android 上,标签必须是本地的图像或视频 URI,例如"file:///sdcard/img.png"。
在 iOS 上,标签可以是任何图像 URI(包括本地、远程资产库和 base64 数据 URI)或本地视频文件 URI(此时不支持远程或数据 URI 来保存视频)。
为了做到能够不直接在页面写组件而能显示出各种组件
react-native-root-siblings
yarn add react-native-root-siblings
表情
图片选择器
react-native-syan-image-picker
yarn add react-native-syan-image-picker
IOS 配置
- 安装
cd ios && pod install
- 添加相册相关权限
Info.plist
Privacy - Camera Usage Description 是否允许此App使用你的相机进行拍照?
Privacy - Photo Library Usage Description 请允许访问相册以选取照片
Privacy - Photo Library Additions Usage Description 请允许访问相册以选取照片
Privacy - Location When In Use Usage Description 我们需要通过您的地理位置信息获取您周边的相关数据
- 中文适配
添加中文 PROJECT -> Info -> Localizations 点击"+"按钮,选择Chinese(Simplified)
Android 配置
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
UI 框架
有值得学习借鉴的地方
便于数据的操作与易用的数据类型
轻量级的 immutable.js {Immer.js}+可简易操作的对象 useImmer
yarn add immer use-immer
网络状态
@react-native-community/netinfo
yarn add @react-native-community/netinfo
cd ios && pod install
新增启动图
react-native-splash-screen
yarn add react-native-splash-screen
cd ios && pod install
IOS
AppDelegate.m
+ #import "AppDelegate.h"
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import "RNSplashScreen.h" // 添加这一句
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// ...other code
+ [RNSplashScreen show]; // 添加这一句,这一句一定要在最后
return YES;
}
@end
直接修改
LaunchScreen.storyboard
就好了
ANDROID
package com.technicianuser;
import com.facebook.react.ReactActivity;
+ import org.devio.rn.splashscreen.SplashScreen;
+ import android.os.Bundle;
public class MainActivity extends ReactActivity {
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "technicianUser";
}
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ SplashScreen.show(this); // here
+ super.onCreate(savedInstanceState);
+ }
}
main/res/layout/launch_screen.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- https://developer.android.com/guide/topics/ui/layout/relative?hl=zh-cn-->
<TextView
android:id="@+id/appName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/app_name"
android:textColor="#F2A160"
android:layout_marginTop="200dp"
android:textSize="36sp" />
<TextView
android:id="@+id/desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/app_desc"
android:layout_alignParentBottom="true"
android:layout_marginBottom="50dp"
/>
</RelativeLayout>
打分星星
react-native-ratings
yarn add react-native-ratings
获取设备信息
react-native-device-info
yarn add react-native-device-info
ios
cd ios && pod install
清除缓存
react-native-clear-cache
package.json
+ "react-native-clear-cache": "https://github.com/sowlutions/react-native-clear-cache"
ios
cd ios && pod install
侧滑
react-native-swipeable
yarn add react-native-swipeable
毛玻璃
react-native-blur
yarn add @react-native-community/blur
cd ios && pod install
应用处理离线状态
react-native-offline
yarn add react-native-offline
yarn add @react-native-community/netinfo
cd ios && pod install
城市索引选择
yarn add react-native-spring-scrollview react-native-largelist-v3 react-native-spinkit
cd ios && pod install
react-native-spring-scrollview 可能会遇到以下这个错误
react-native-spring-scrollview 弹性滚动
react-native-spring-scrollview
/Library/work/technicianUser/node_modules/react-native-spring-scrollview/ios/SpringScrollView/STSpringScrollView.m:25:42: Expected a type
最顶上加一个
#import "STSpringScrollView.h"
+ #import "RCTEventDispatcher.h"
---->直接下载到本地【从本地导到 node_modules】
currentlyFocusedField => currentlyFocusedInput
这个 bug 也需要修复一下
SpringScrollView.js
- import * as TextInputState from "react-native/lib/TextInputState";
+ import * as TextInputState from 'react-native/Libraries/Components/TextInput/TextInputState'
避免远程 bug 未修复从而出现错误,自己手动改
package.json
直接连接到本地
react-native-spring-scrollview/src
[只要这 src 里面的] 文件下新增 react-native-spring-scrollview.podspec
require "json"
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
Pod::Spec.new do |s|
s.name = "react-native-spring-scrollview"
s.version = package["version"]
s.summary = package["description"]
s.description = <<-DESC
react-native-spring-scrollview
DESC
s.homepage = "https://github.com/bolan9999/react-native-spring-scrollview"
s.license = "MIT"
# s.license = { :type => "MIT", :file => "FILE_LICENSE" }
s.authors = { "Your Name" => "yourname@email.com" }
s.platforms = { :ios => "9.0", :tvos => "10.0" }
s.source = { :git => "https://github.com/bolan9999/react-native-spring-scrollview.git", :tag => "#{s.version}" }
s.source_files = "ios/**/*.{h,m,swift}"
s.requires_arc = true
s.dependency "React"
# s.dependency "..."
end
因为没有使用 src 里面的,报了以下错误
报错 "The react-native-spring-scrollview
pod failed to validate due to 1 error: - ERROR | attributes: Missing required attribute summary
"
package.json
加 description 字段[description 不能为空]
tab 块选择
轮播
react-native-swiper
yarn add react-native-swiper
Tab 选项卡
react-native-tab-view
结合 react-native-head-tab-view
react-native-tab-view
版本 3 需要多安装react-native-pager-view
yarn add react-native-head-tab-view react-native-gesture-handler react-native-reanimated react-native-tab-view-collapsible-header react-native-tab-view react-native-pager-view
android react-native-reanimated 安装需要加代码
docs.swmansion.com/react-nativ…
babel.config.js
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
+ plugins: ['react-native-reanimated/plugin'],
};
配置完还是报错Reanimated 2 failed to create a worklet, maybe you forgot to add Reanimated's babel plugin?
:有缓存
yarn start --reset-cache
@surajj2223:github.com/software-ma…
IOS
cd ios && pod install
地图选择 下拉选择做准备
yarn add reanimated-bottom-sheet
Now we need to install react-native-gesture-handler and react-native-reanimated.
查看更多 源码
左滑 菜单类似 QQ
picker
地图
地图
ios 存在问题 github.com/qiuxiang/re…
api 定位
优化打包 bundle
Android 生成 keystore
keytool -genkey -v -keystore app.keystore -alias zhiyue -keyalg RSA -keysize 2048 -validity 100000
解决弧度曲线
react-native-svg
yarn add react-native-svg
cd ios && pod install
解决阴影
yarn add @react-native-community/art react-native-neomorph-shadows
cd ios && pod install
权限 API 管控
yarn add react-native-permissions
⚠️ If you see a No permission handler detected error: Make sure that you have at least one permission handler set up. In some cases the Xcode cache needs to be cleared (Xcode -> Product -> Clean Build Folder)
这里面选几条加到 Podfile 里面
iOS 隐私权限和通过 openURL 实现跳转
系统级别的 toast
react-native-toast-native
yarn add react-native-toast-native
查看更多
学习如何写自己模块
学习别人的的大框架
画虚线
react-native-dash
yarn add react-native-dash react-native-measureme
可以研究一下 setNativeProps
生成二维码
react-native-qrcode
yarn add react-native-qrcode
----不太行的样子
换
直接源码重写
图片合成
yarn add react-native-view-shot
关于地图计算的库
跟微信相关 登录分享 库
集成 qq 相关 登录
极光推送
fish.iwhalecloud.com/fish-mobile…
状态管理
文档
oss-labs.gitbook.io/dva-docs/mo…
时间库
获取最新省市区脚本
升级 python 到 3 --blog.csdn.net/alice_tl/ar…
台湾+香港+台湾数据整合 blog.csdn.net/u010318957/…
---- 记录获取港澳台数据 github.com/youzan/vant…
// vant 获取数据
var a={....}
var b={....}
var arr=[]
for(let i in a){
let area=[]
for(let j in b){
if(j.indexOf(i.slice(0,4))>-1){
area.push({code:j,value:b[j],label:b[j]})
}
}
arr.push({code:i,value:a[i],label:a[i],children:area})
}
codechina.csdn.net/mirrors/wu-…
# -*- coding: UTF-8 -*-
import json
import urllib.request
# import requests
import urllib.parse
import ssl
import os
import time
from bs4 import BeautifulSoup
# config #
year = '2019' # 年份,目前国家统计局官网有2009-2019年的数据
level = 3 # 可选:3|5 获取的层级 3层为省-市-区 最多5级省-市-区-县(街道)-乡镇(居委会)
digit = 6 # 可选:6|12 行政区划代码位数 层级为3级时通常使用6位代码 如110000,层级为5级时使用12位代码 如 110000000000
head_url = "index" # 可选:index|各省行政区划前两位 要从哪开始获取 index为全国所有省份 要获取单独的省份修改为省行政区划的前两位
# config #
context = ssl._create_unverified_context()
headers = {
'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'
}
mainUrl = 'http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/'
attrsClassArr = ['provincetr', 'citytr', 'countytr', 'towntr', 'villagetr']
def is_CN(word):
for ch in word:
if '\u4e00' <= ch <= '\u9fff':
return True
return False
def retry(times):
def wrapper(func):
def inner_wrapper(*args, **kwargs):
i = 0
while i < times:
try:
if i > 0:
print('正在尝试第%d次请求' % (i+1))
return func(*args, **kwargs)
except:
# 此处打印日志 func.__name__ 为say函数
print('%s 请求失败!' % (args[0]))
# print("logdebug: {}()".format(func.__name__))
i += 1
return inner_wrapper
return wrapper
@retry(5)
def fetchAreaData(url, index, attrsClass, area):
if index < level:
try:
with urllib.request.urlopen(url, context=context, timeout=3) as response:
soup = BeautifulSoup(response.read(), 'html.parser')
tag = soup.find_all(attrs={"class": attrsClass})
for tg in tag:
villageArr = []
for tgc in tg.children:
if tgc.a:
if is_CN(tgc.a.get_text()):
print('正在请求', '/'.join(url.split('/')
[0:-1]) + '/' + tgc.a.attrs['href'], tgc.a.get_text())
if index + 1 == level:
area.append(
{"value": tgc.a.attrs['href'].split('/')[-1].replace('.html', '').ljust(digit, '0'), "label": tgc.a.get_text()})
else:
content = {"value": tgc.a.attrs['href'].split(
'/')[-1].replace('.html', '').ljust(digit, '0'), "label": tgc.a.get_text(), "children": []}
area.append(content)
fetchAreaData(
'/'.join(url.split('/')[0:-1]) + '/' + tgc.a.attrs['href'], index+1, attrsClassArr[index+1], area[len(area)-1]['children'])
elif attrsClass == 'villagetr':
villageArr.append(tgc.get_text())
if len(villageArr) > 0:
area.append(
{"value": villageArr[0], "label": villageArr[2]})
except urllib.request.URLError as e:
print("出现异常: "+str(e))
position = 0
areas = []
if head_url != 'index':
position = 1
fetchAreaData(mainUrl+year+'/'+head_url+'.html',
position, attrsClassArr[position], areas)
with open(head_url+'_'+year+'_'+"_level_" + str(level)+'.json', "w", encoding='utf-8') as json_file:
json.dump(areas, json_file, ensure_ascii=False)
print("写入%s完成" % (head_url+'_'+year+'_'+"_level_" + str(level)+'.json'))
# code = ['11', '12', '13', '14', '15', '21', '22','23', '31', '32', '33', '34', '35', '36', '37',
# '41', '42', '43', '44', '45', '46', '50', '51', '52', '53', '54', '61', '62', '63', '64', '65']
# for index in range(24):
# areas = []
# head_url = code[index]
# position = 0
# if head_url != 'index':
# position = 1
# fetchAreaData(mainUrl+year+'/'+head_url+'.html',
# position, attrsClassArr[position], areas)
# with open('province/level_5/'+head_url+'_'+year+'_'+"_level_" + str(level)+'.json', "w", encoding='utf-8') as json_file:
# json.dump(areas, json_file, ensure_ascii=False)
# print("写入%s完成" % (head_url+'_'+year+'_'+"_level_" + str(level)+'.json'))
React Hooks 请求库
有点东西