React Native 沿用 React 的组件与状态模型,渲染目标是平台组件。View、Text、TextInput 不是 div、p、input 的简单改名;样式、事件、文本布局和原生能力都有自己的契约。网页代码中的 document、CSS 选择器和 localStorage 不能直接作为跨平台方案。

样式和输入

样式通常通过 JavaScript 对象与 StyleSheet 表达,布局常使用 Flexbox,但默认值和支持属性需要按 React Native 文档核对。文本应放在 Text 中;TextInput 用 value 与 onChangeText 处理受控输入。软键盘会改变可用空间,长表单要考虑滚动与 KeyboardAvoidingView,并在真实设备检查。

Pressable 适合表达按压动作;需要提供 accessibilityRole、名称和必要状态。不能只靠颜色表示完成。系统安全区域、状态栏、横竖屏和系统文字缩放都属于布局输入。

列表与状态

<FlatList
  data={lessons}
  keyExtractor={item => item.id}
  renderItem={({ item }) => (
    <Pressable
      accessibilityRole="checkbox"
      accessibilityState={{ checked: item.done }}
      onPress={() => toggle(item.id)}>
      <Text>{item.done ? "已学:" : "待学:"}{item.title}</Text>
    </Pressable>
  )}
/>

这是组件片段,lessons 和 toggle 由应用提供。FlatList 对长列表做虚拟化,数据仍应有稳定 ID。它采用浅比较相关策略;如果单项显示依赖 data 之外的状态,要确保这些变化通过 props/extraData 传入。列表外的对象没变,不代表内部可变字段就一定触发正确更新。

不要把大型数组全部放进 ScrollView 后才考虑性能。getItemLayout 只在尺寸可可靠计算时使用;强写错误高度会造成滚动定位问题。渲染批量、窗口大小与图片尺寸都应通过真实场景测量。

生命周期与原生能力

应用进入后台不一定立即卸载 React 组件。定时器、订阅和网络工作要结合 AppState 与页面焦点管理;Effect 清理解决组件生命周期,不能代替所有平台生命周期。相机、定位和文件等插件还需要权限、原生配置与错误处理。

Expo 提供统一工具与很多原生能力,适合起步;需要新增原生依赖时,Expo Go 的能力范围可能不够,要使用开发构建等方式。原生依赖改变通常需要重新构建,不能把热更新当成原生代码升级。iOS、Android 和 Web 的能力、发布与审核分别验证。

性能排查要区分 JavaScript 工作和平台 UI 工作。复杂计算、频繁创建大对象或大量重渲染可能拖慢交互;图片、布局和原生视图也有自己的成本。使用发布条件和对应分析工具测量,不把开发日志、远程调试环境下的单次计时当作最终结论。优化列表窗口或记忆化之前,先确认实际慢在什么动作与线程。参见 React Native 性能概览。

练习:解释为什么后台回来后数据可能过期,为什么 Effect 仍未重跑;为列表项增加单独的选择状态,并判断是否需要 extraData。继续完成React Native 记录板。

面试自查:React Native 为什么不能直接使用 DOM API?FlatList 的数据身份与额外状态如何影响更新?组件卸载和应用进入后台为什么需要分别处理?

参考:React Native 起步、FlatList、平台差异、Expo 开发构建。