前言

本篇接着前面的RN学习旅程,继续来写RN的学习笔记。

1、工程目录结构

index.js

  • index.js为默认入口文件,负责RN工程根节点初始化
  • 核心逻辑:
    • 从react-native包导入AppRegistry.registerComponent方法
    • 调用该方法注册根组件,组件名通过app.json的name字段获取
    • 根组件实例从同级目录的App.js导入

package.json和package-lock.json

文件

功能

注意事项

package.json

定义全局变量(如name/version)、脚本命令及依赖项

可手动编辑配置

package-lock.json

锁定依赖版本(如react-native - - 6)

删除后执行npm install会重新生成

babel.config.js

  • 配置Babel翻译器,默认使用module:metro-react-native-babel-preset预设
  • 预设(preset)为插件集合包,简化配置流程

app.json

  • 纯JSON结构,定义工程常量(如name/displayName)
  • 通过import语句可直接引用其中字段

node_modules

  • node_modules文件夹存储所有第三方依赖库(如react-native - - 6源码包)
  • 与原生开发差异:
    • 文件可修改且实时生效
    • 重新执行npm install会覆盖本地修改

android和iOS

  • android目录:对应原生Android工程,包含Gradle配置及模块代码
  • ios目录:对应原生iOS工程,包含Xcode项目文件及Pod配置
  • 关键特性:RN通过这两个目录实现与原生平台的桥接

2、通用源码目录结构

  • 模块划分:
    • modules/:业务功能模块(替代pages更通用)
    • components/:可复用UI组件库
    • assets/:静态资源(图片/SVG/音频)
    • constants/:全局配置/密钥等常量
    • env/:多环境配置(测试/生产环境域名等)
  • 扩展功能:
    • hooks/:自定义React Hooks集合
    • store/:全局状态管理(登录信息等)
    • utils/:工具函数库
    • apis/:网络接口统一管理(包含请求方法/路径等)
    • theme/:多主题支持(日间/夜间模式)

3、package.json介绍

文件格式: 后缀名为.json的纯JSON格式文件,包含大括号包裹的多个字段定义

核心作用: 管理React Native工程的所有配置和依赖关系

基础字段:

  • name: 应用名称,如示例中的"demo"
  • version: 应用版本号,格式为"主版本.次版本.修订号",如"0.0.1"
  • private: 布尔值,设为true可防止工程被意外发布到npm仓库
    • 注意: 当设置为true时,执行npm publish会报错

自定义脚本:

  • scripts: 定义可通过npm run执行的命令
    • 运行原理: npm run后接scripts对象中定义的键名
    • 常用命令:
      • "android": "react-native run-android"
      • "ios": "react-native run-ios"

包依赖:

  • dependencies: 生产环境依赖包,会打包到最终应用中
  • devDependencies: 开发环境依赖包,仅用于开发阶段

4、import和export

①、import导入

  • 文件创建:在src/constants目录下创建Config.json文件
  • 内容格式:直接定义JSON对象,无需export语句
  • 导入方式:使用import Config from './src/constants/Config.json'
  • 使用方法:
    • 直接访问属性:Config.name获取"zhangsan"
    • 字符串化输出:JSON.stringify(Config)

②、export导出

  • 单函数导出:
    • 导入方式:import test from './path'
  • 多函数导出:
    • 导入方式:import {test, test2} from './path'
  • 区别要点:
    • default导出时import不需要花括号
    • 非default导出必须使用花括号按名称导入
    • 一个模块只能有一个default导出

知识点

核心内容

关键代码示例

应用场景

JSON文件导入

直接导入JSON格式配置文件

import config from './constants/config.json'

静态配置数据加载

默认导出(export default)

单个函数/组件的默认导出方式

export default test

单功能模块封装

命名导出(export)

多个函数/组件的显式导出

export {test, test2}

多功能工具库开发

组件导入

Vue组件文件的导入与使用

import TestView from './components/TestView'

前端组件化开发

JSON数据访问

导入后JSON对象的属性访问

config.name config.age

配置参数读取

函数调用

导入后的工具函数调用

test() test2()

工具方法复用

动态组件渲染

导入组件在模板中的使用

<TestView />

可视化组件复用

5、class组件和函数式组件

5.1、class组件

  • 开发范式: React提供的两种开发范式之一,传统且完整
  • 状态管理:
    • 使用state管理组件状态
    • 每次修改都是修改同一个状态对象
  • 基本结构:
    • 必须继承

      React.ComponentReact.ComponentReact.Component

    • 必须实现render()方法
  • 状态声明:
    • 通过constructor初始化state
    • 使用

      this.setState()this.setState()this.setState()

      更新状态
  • 生命周期方法:
    • 包含componentDidMount等钩子函数
    • 完整控制组件各阶段行为

class组件的标准写法

  • 基本结构:
  • 继承关系:必须继承React.Component基类,通过extends React.Component实现
  • 导入要求:
    • RN组件需单独从'react-native'导入(如View组件)
    • React核心库必须导入(import React from 'react')
  • 引号规范:JSX中单引号和双引号均可使用,不同代码规范可能有不同要求
  • 构造函数:
    • 必须接收props参数
    • 必须调用super(props)初始化父类
  • 渲染方法:
    • 必须实现render()方法
    • 必须返回JSX元素(如示例中的View组件)
    • 可通过style属性设置样式(如宽高200、红色背景)

5.2、函数式组件

  • 开发范式: React推荐的现代开发方式
  • 状态管理:
    • 通过useState等Hook管理状态
    • 每次渲染生成全新状态对象
  • 管理方式:
    • 基于状态变化而非生命周期
    • 使用useEffect替代生命周期
  • 优势:
    • 代码简洁模板少
    • 逻辑复用更方便
    • 社区主流选择(99%场景适用)

①、三种写法:

  • 基本写法:使用function关键字定义组件,如function FunctionView() {...}
  • 箭头函数写法:使用const声明箭头函数,如const FunctionView = () => {...}
  • 匿名导出写法:直接导出匿名箭头函数,如export default () => {...}
  • 优势:相比class组件更简洁,没有模板代码,写法灵活自由

②、函数式组件传参

  • 参数接收:通过函数参数props接收父组件传递的值
  • 解构赋值:可以直接解构props中的属性,如const {name, age} = props
  • 使用差异:函数组件中直接使用props,不需要通过this访问
  • 注意事项:函数组件没有this指针,任何地方都直接使用props参数

③、函数式组件的state

useState使用:

  • 声明方式:使用const [state, setState] = useState(initialValue)
  • 更新方法:每个state对应独立的setter函数,如setAddress(newValue)
  • 初始值:useState参数为state的初始值
  • 特点:state变化会触发组件重新渲染

useEffect使用:

  • 基本用法:useEffect(() => {...}, [deps])
  • 生命周期模拟:空依赖数组相当于componentDidMount
  • 副作用监听:依赖数组中变量变化时会触发回调
  • 执行顺序:先执行render(return)再执行useEffect回调
  • 特殊行为:初始赋值会被视为一次变化而触发回调
  • 多effect:可以定义多个useEffect分别监听不同变量

④、常用Hook

useRef:

  • 作用:获取DOM节点引用,实现命令式编程
  • 使用场景:当数据驱动UI无法满足需求时

useWindowDimension:

  • 作用:获取设备屏幕的宽高
  • 返回值:逻辑单位而非物理像素
  • 注意事项:
    • 返回值是逻辑单位(如392×813)
    • 不同于设备的实际物理分辨率

useColorScheme:

  • 作用:获取系统当前的主题模式(dark/light)
  • 返回值:'dark'或'light'
  • 应用场景:
    • 实现APP的暗黑模式适配
    • 根据系统主题自动切换UI样式

总结:

分类

知识点

核心内容

关键区别

应用场景

Class组件

生命周期管理

基于构造函数初始化、componentDidMount、render顺序执行

有状态组件,通过this.state维护内部状态

传统项目维护、需要明确生命周期控制的场景

函数式组件

Hooks机制

使用useState管理状态、useEffect处理副作用

无状态组件,每次渲染都是新实例

现代项目开发、追求代码简洁和复用的场景

Props传值

组件通信

父组件通过属性传递数据,子组件通过this.props接收

外部控制,数据由父组件维护

组件层级数据传递、配置型组件开发

State管理

状态维护

通过this.setState更新内部状态触发UI刷新

内部控制,数据由组件自身维护

交互型组件开发、需要自主管理状态的场景

开发趋势

范式对比

Class组件更符合传统OOP思想,函数式组件更简洁

函数式组件已成为主流开发方式

新项目推荐使用函数式组件,旧项目可能需要兼容Class组件

6、JSX语法

①、标准写法和简略写法

标准箭头函数写法:

  • 完整结构包含参数括号、箭头符号和函数体花括号
  • 必须显式使用return语句返回JSX元素
  • 示例:const getLevelView = () => { return <Text>等级:高级</Text> }

一级简写形式:

  • 当函数体仅包含return语句时,可省略花括号和return关键字
  • 需保留参数括号和箭头符号
  • 示例:const getLevelView = () => (<Text>等级:高级</Text>)

二级简写形式:

  • 当返回单行JSX时,可进一步省略参数括号
  • 最简形式:const getLevelView = () => <Text>等级:高级</Text>
  • 实际应用:React Native默认模板中的() => App就是这种简写

适用场景:

  • 简写适合纯展示型组件
  • 包含复杂逻辑时建议使用标准写法
  • 注意保持代码可读性,过度简写可能影响维护

②、拆分渲染

  • 定义: 将复杂的渲染逻辑拆分为多个独立模块的方法
  • 应用场景: 当页面包含几十上百个组件时,全部写在一起会导致代码难以维护
  • 优势:提高代码可读性、便于后期维护、模块化开发更清晰
  • 其它拆分方式:组件拆分

③、样式表

样式应用:

  • 内联样式:直接写在组件style属性中
  • 样式表:集中管理样式规则

样式表的使用方式:

  • 导入方式:从react-native包中导入StyleSheet
  • 创建方法:使用StyleSheet.create()方法,传入一个包含所有样式的对象
  • 返回值:返回一个styles对象,包含页面或组件所需的所有样式
  • 引用方式:通过styles.root或styles.txt等方式引用定义好的样式
  • 样式组合:通过数组形式组合多个样式,如style={[styles.txt, styles.special]}

④、其它渲染方式

条件渲染:true or false

三元表达式:condition ? true : false

短路写法:condition && <Component/> 实现条件成立时渲染

列表渲染:array.map(item => <Text>{item}</Text>)

数组渲染:for循环中viewList.push(<Text>List item {i+1}</Text>)

本篇笔记到此结束,下期再会!

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐