• ReactNative踩坑及技术方案总结(2022 持续更新中)


    一、写在前面

    1. 前言

      经过将近一个月的学习和开发,也做出了第一个由RN开发的 Android 应用。该文章旨在将近期学习的 React Native 所踩的坑、技术方案进行总结,为之后的开发留下可参考的财富,减少重复造轮子、踩坑的时间。(你所深陷的困境,可能别人早已轻而易举地解决,不要把脑力花在这上面!除非你想自己造轮子。)

    2. 总结路线

    1. 环境、框架搭建相关
    2. 基础组件
    3. 第三方组件
    4. 样式
    5. 代码实现
    6. 常见报错

    3. 输出内容

    1. 环境搭建:傻瓜式可操作步骤(参考「菜谱」)
    2. 组件:最简单用法 -> 效果 -> 扩展用法(参考「UI库官方文档」)
    3. 样式:希望实现的效果 -> 写法
    4. 代码实现:希望实现的功能 -> 写法 -> 注意点
    5. 报错:报错内容 -> 报错原因 -> 解决办法

    二、环境、框架搭建

    1. 在电脑上安装多个JDK版本

    要让 RN 跑起来,JDK 环境是必须的,网上已有非常多的 JDK 安装教程,找一篇跟着操作即可

      这里要解决的问题是:假设我电脑上已原有 JDK8 版本,而官方文档要求如果 RN 版本 >= 0.67,则需要 JDK11 的版本。那么此时我该如何 **同时配置两个JDK环境?**操作步骤如下:

    1. 先正常安装 JDK8 和 JDK11 两个版本
    2. 安装完成后,按照下图步骤,配置两个环境变量,分别是 JAVA8_HOMEJAVA11_HOME

    image.png

    1. 若在当前电脑需要切换到 JDK8 的环境,则在Path里配置如下(JDK11同理),并点击确定

    image.png

    1. Path里将要使用的JDK版本放在最前面,即可完成切换

    image.png

    1. 最后需打开 的cmd窗口,输入java -version验证当前版本是否已切换成功

    如下图,即代表当前环境为 JDK11

    image.png

    2. 真机进行网络调试

    方式一:react-native-debugger

    方式二:reactotron【推荐】

    Reactotron 官方链接:https://github.com/infinitered/reactotron/blob/master/docs/quick-start-react-native.md

    其使用非常简单,根据官方文档进行操作即可,大体分为两个步骤:

    1. 安装本地客户端
    2. 在项目代码中配置后,重新编译即可生效,并在客户端中看到效果如图

    image.png


    三、基础组件

    1. TouchableOpacity

      有点击样式的 块元素

    可以理解为:加了 hover 样式的 div。与之不同的是,在RN中, 无法添加 onPress 来触发点击事件,因此需要在 外层套一个

    import { TouchableOpacity, Text  } from 'react-native'
    
    const handlePress = () => { ... }
    
    const Index = () => {
      <TouchableOpacity onPress={handlePress} activeOpacity={0.5}>
        <View></View>
      </TouchableOpacity>
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    常用属性:

    • activeOpacity:控制手指按下时,元素的透明度变化值(类似css的 div:hover { opacity: 0.5 }

    四、样式

    1. 响应式

    UI给出的设计稿的屏幕宽度通常都是 375,也就是以 iPhone6 作为标准来设计,而实际开发中,为了适配各种机型的显示,我们需要声明如下函数,并在样式中使用它

    1. 声明
    // src/utils/stylesKits.js
    import {Dimensions} from 'react-native';
    
    // 手机中元素的宽度 = 手机屏幕 * 元素宽度 / 设计稿宽度(以375为例)
    export const screenWidth = Dimensions.get('window').width;
    export const screenHeight = Dimensions.get('window').height;
    
    export const pxToDp = elePx => (screenWidth * elePx) / 375;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 使用
    // xxx.js 组件中编写styles时引用
    import {pxToDp} from '../../utils/stylesKits';
    
    const styles = StyleSheet.create({
      image: {
        width: pxToDp(150),
        height: pxToDp(150),
      }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2. 沉浸式导航栏

    使用的路由和导航栏组件是 @react-navigation/native-stack

    参考文档:https://reactnavigation.org/docs/native-stack-navigator

    当希望实现类似「沉浸式导航栏」时,我们需要把顶部的导航栏隐藏,实现如下:

    方法一:【不推荐,会占位】将导航栏的背景色和字体色调整成和页面背景色一致即可

    
      {
          headerStyle: {
            backgroundColor: '#fff',
          },
          // 隐藏标头上的高程阴影 (Android) 或底部边框 (iOS)。
          headerShadowVisible: false,
          headerTintColor: '#fff',
        }}
        />
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    方法二:【推荐】将 header 设置成 null

    header 实际用途是:自定义标题栏,此时返回 null 相当于自定义了一个没有任何结构的导航栏,达到了隐藏原生导航栏的目的

    
      {
              header: () => {
                return null
              },
            }}
        />
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3. 设置渐变色

    RN 无法像 CSS 一样,直接通过 linear-gradient 就可以设置渐变色

    需要引入第三方插件 https://www.npmjs.com/package/react-native-linear-gradient

    1. 安装
    yarn add react-native-linear-gradient
    
    • 1
    1. 简单使用
    <LinearGradinet
      start={{x: 0, y: 0}}
      end={{x: 1, y: 0}}
      colors={['#9b63cd', '#e0708c']}
      style={{width: 200, height: 200}}
    />
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    五、写法

    1. useEffect 中使用异步函数

      当我尝试中 useEffect 中用如下代码写「异步函数」时,报错如下

      useEffect must not return anything besides a function, which is used for clean-up.

    // 错误写法
    useEffect(async () => {
      ...
    }, []);
    
    • 1
    • 2
    • 3
    • 4

      正确写法如下

    // 正确写法
    useEffect(() => {
      (async () => {
        ...
      })();
    }, []);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2. 缓存

    原生自带的 AsyncStorage 已被官方废弃,其推荐使用社区的包

      因此,我们使用 @react-native-async-storage/async-storage(社区的其他包也可以,该包较为容易上手),地址:https://react-native-async-storage.github.io/async-storage/docs/install。简单使用如下:

    1. 安装
    yarn add @react-native-async-storage/async-storage
    
    • 1
    1. 在需要使用的地方导入
    import AsyncStorage from '@react-native-async-storage/async-storage';
    
    • 1
    1. 写入缓存

    ① 写入的是如「字符串」之类的值类型

    const storeData = async (value) => {
      try {
        await AsyncStorage.setItem('@storage_Key', value)
      } catch (e) {
        // saving error
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    ② 写入的是如「对象、数组」之类的引用类型(需要先将对象转换成字符串)

    const storeData = async (value) => {
      try {
        const jsonValue = JSON.stringify(value)
        await AsyncStorage.setItem('@storage_Key', jsonValue)
      } catch (e) {
        // saving error
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 读取缓存

    ① 读取「字符串」之类的值类型

    const getData = async () => {
      try {
        const value = await AsyncStorage.getItem('@storage_Key')
        if(value !== null) {
          // value previously stored
        }
      } catch(e) {
        // error reading value
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    ② 读取「对象、数组」之类的引用类型

    const getData = async () => {
      try {
        const jsonValue = await AsyncStorage.getItem('@storage_Key')
        return jsonValue != null ? JSON.parse(jsonValue) : null;
      } catch(e) {
        // error reading value
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    C++图像金字塔下采样的函数
    mysql 事务
    【操作系统 | Linux】终端切换与帮助命令
    【C++】STL简介 | string类的常用接口
    Java集中常见的排序
    正雅:你的隐形矫正方案选对了吗?
    对比学习孪生网络之简单的手写数字集代码实战
    JSON常用注解
    Git使用及配置
    numpy 最小二乘拟合 一元线性回归与多元线性回归 原理与代码
  • 原文地址:https://blog.csdn.net/weixin_42678675/article/details/126965024