发布于 2026-01-05 8 阅读
0

Lessons learned while building my React Native mobile app Choose Third-party Libraries Carefully Avoid Using Native Extensions as much as Possible Support UI Themes Add Tablet Support Keep It Performant Make A Perfect Splash Screen Don’t Use CodePush

在构建我的 React Native 移动应用过程中学到的经验教训

谨慎选择第三方库

尽可能避免使用原生扩展

支持用户界面主题

添加平板电脑支持

保持性能

打造完美的启动画面

不要使用 CodePush

我正在开发一款名为Inkdrop的 Markdown 笔记应用,最近发布了适用于 iOS 和 Android 的新版移动应用。它使用React Native构建,React Native 是一个使用 JavaScript 和 React 构建原生移动应用的框架。

我从这个项目中学到了很多关于如何使用 React Native 创建高质量移动应用程序的知识,我想在本文中分享我的技巧。

我希望这篇文章能对那些已经开发或正在开发 React Native 移动应用的人有所帮助。

以下是我们将要涵盖的内容概要。

  • 谨慎选择第三方库

  • 尽可能避免使用原生扩展。

  • 支持用户界面主题

  • 添加平板电脑支持

  • 保持性能

  • 打造完美的启动画面

  • 不要使用 CodePush

谨慎选择第三方库

与 iOS 上的 UIKit 不同,React Native 在构建炫酷的 UI 或导航方面提供的功能并不多。因为它专注于使用 React 和 JavaScript 提供基本的 UI 渲染和设备 API 访问。所以,你需要做很多工作才能让它看起来像你想要的那样。说实话,如果没有使用 React Native 上那些优秀的模块,我根本不可能完成这个项目。接下来我会告诉你我的应用使用了哪些库。

导航

如上图所示,我的应用程序有一个侧边栏,可以通过从屏幕左边缘滑动或点击工具栏按钮来激活,它还包含堆叠屏幕和模态屏幕。

为了实现路由和导航,我的应用采用了react-navigation。您可以轻松实现灵活的路由和流畅的屏幕过渡。但请注意,它不提供模态屏幕。您应该使用react-native-modal,它提供了增强的、动画效果好且可自定义的 React Native 模态屏幕。

如果您不需要非常特殊的布线模式,我强烈建议您使用它们。如果您需要,请查看这篇很棒的文章

丰富的跨平台 UI 组件

iOS 和 Android 的 UI 设计规范不同。要实现符合两个平台标准的按钮、表格和标题,既困难又耗时。虽然市面上有很多美观的第三方组件,但你需要在应用中安装大量模块,最终会导致应用臃肿不堪,并出现各种 bug。

NativeBase

NativeBase是一套适用于 React Native 的跨平台 UI 组件库,它解决了这个问题。它类似于 React Native 版的 Twitter Bootstrap。它不仅提供了一套设计精良的基础组件,还包含一些布局组件。您无需担心应用运行在哪个平台上,因为组件样式会自动切换。

尽可能避免使用原生扩展

由于 React Native 是一项前沿技术,其 API 经常变更,这往往会导致第三方库无法正常工作。如果问题出在原生端,解决起来将异常艰难。对于库的开发者来说,这始终是一个难题,因为:

我们发现,大多数 React Native 开源项目都是由只有一两个平台经验的人编写的——例如Airbnb。

他们并非都是所有平台的专家。我曾为 React Native 开发过一个SQLite3 原生插件,也发现维护这两个平台相当困难。

如果你决定安装带有原生桥接器的库,就必须记住这一点。我经常需要查看原生代码来调试问题,所以你需要一些 iOS 和 Android 方面的经验。避免使用这些原生桥接库可以减少这种麻烦。

以下是我的应用中使用的所有带有原生桥接功能的库:

减少对原生扩展的依赖,可以使你的应用更容易维护,以便兼容未来的 React Native 版本。

支持用户界面主题

对于 React Native 应用来说,支持主题是一项挑战,因为这完全取决于视图的渲染方式。与 iOS UIKit 不同,React Native 不提供任何外观代理,因此你需要为 React Native 开发一个等效的外观代理。

幸运的是,NativeBase 支持主题化。您只需定义如下变量,即可轻松自定义 NativeBase 组件的外观:

const $defaultBgColor = '#2E3235'
const $defaultFgColor = 'rgba(255, 255, 255, 0.7)'

const nativeBaseTheme = {
    toolbarBtnColor: $defaultFgColor,
    toolbarBtnTextColor: $defaultFgColor,
    toolbarDefaultBg: $defaultBgColor,
    toolbarDefaultBorder: 'rgba(0, 0, 0, 0.3)',
}

<StyleProvider variables={nativeBaseTheme}>
  <View>...</View>
</StyleProvider>
Enter fullscreen mode Exit fullscreen mode

但这还不够,因为它不适用于非 NativeBase 组件。所以我使用了react-native-extended-stylesheet,它允许你在样式表中使用变量,如下所示:

// app entry: set global variables and calc styles
EStyleSheet.build({
  $bgColor: '#0275d8'
});

// component: use global variables
const styles = EStyleSheet.create({
  container: {
    backgroundColor: '$bgColor'
  }
});

<View style={styles.container}>
...
</View>
Enter fullscreen mode Exit fullscreen mode

非常简单。现在您可以定义所有组件的外观了!

注意:需要重新启动才能应用新主题,因为NativeBase StyleProvider 会缓存样式,目前没有办法清除缓存

添加平板电脑支持

如果您想为平板电脑制作双栏布局,这很简单:

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row'
  },
  leftViewContainer: {
    flexShrink: 0,
    flexGrow: 0,
    width: 200
  },
  rightViewContainer: {
    flex: 1
  }
})

<View style={styles.container}>
  <View style={styles.leftViewContainer}>
    ...
  </View>
  <View style={styles.rightViewContainer}>
    ...
  </View>
</View>
Enter fullscreen mode Exit fullscreen mode

然而,它需要一些技巧才能支持根据屏幕尺寸切换布局,因为存在一个问题,即它本身Dimensions 不支持此功能Dimensions.get。即使在 iPad 上使用“分屏浏览”或“侧拉”模式,应用始终显示相同的尺寸。

console.log(Dimensions.get('screen')) // {fontScale: 1, width: 768, height: 1024, scale: 2}
console.log(Dimensions.get('window')) // {fontScale: 1, width: 768, height: 1024, scale: 2}
Enter fullscreen mode Exit fullscreen mode

所以你需要获取窗口的实际大小。为此,你需要创建一个位于最外层的视图,并为其设置样式flex: 1。然后设置onLayout事件来获取窗口大小,并将其存储在某个地方,例如 Redux store 中。

以下是我的代码片段:

保持性能

使用 PureComponents

随着应用程序的不断发展,您最终需要提升应用程序的性能。在 React Native 中,您可以参考以下许多 React 应用程序性能优化技巧:

保持应用运行速度的一个常见基本技巧是使用 `recompose`shouldComponentUpdate()来避免组件不必要的重复渲染。`recompose`React.PureComponent在这方面非常实用,因为它会在组件的 props 没有改变时自动跳过渲染。我个人更喜欢使用`recompose`pure实现高阶组件 (HOC) 模式

不要在 Render() 函数中创建回调函数

render()现在你有了 PureComponents,但如果你有一个像这样的方法,那就没有意义了:

function CommentList(props) {
  return (
    <div>
      {props.comments.map((comment) => (
        <Comment comment={comment} key={comment.id} onPress={() => props.handlePressCommentItem(comment)} />
      ))}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

onPress因为每次渲染 `Comment` 组件时都会创建一个新的函数CommentList,所以 `Comment`(纯组件)会认为它的 props 总是会改变。因此,渲染评论列表会消耗大量资源,因为所有评论都会被重新渲染。为了避免这种情况,请不要创建回调函数:

function CommentList(props) {
  return (
    <div>
      {props.comments.map((comment) => (
        <Comment comment={comment} key={comment.id} onPress={props.handlePressCommentItem} />
      ))}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

如果您的列表可能很长,强烈推荐使用FlatList 。

打造完美的启动画面

避免在 JS 加载过程中出现空白白屏

图。避免在 JS 加载时出现空白白屏。

如果你尝试在 React Native 中设置启动画面,那么你可能遇到过内容加载前屏幕闪过一圈白屏的情况。如果你的应用本身就是白色背景,这种情况通常不太明显,但仍然很烦人。

我推荐你阅读这篇文章,它详细介绍了如何为 iOS 和 Android 构建完美的启动画面。非常有帮助。

不要使用 CodePush

CodePush让您可以轻松地为应用添加动态更新体验。借助 CodePush,您无需每次都通过应用商店发布补丁版本,从而可以快速修复问题。

但我并不建议您使用它。首先,App Store 的审核时间现在非常短。截至撰写本文时,平均只需两天即可完成审核,这对于您的业务来说通常已经足够快了。其次,它会使您的应用变得复杂,因为 CodePush 库是一个原生模块。正如我上面提到的,为了保持应用的简洁性,您应该避免使用原生扩展。

希望这对您有所帮助!

感谢阅读本文!我是松山拓也,一名居住在日本东京的自由开发者。我正在努力独立打造一款盈利产品,并在博客上记录我的创业历程。欢迎访问我的博客!


文章来源:https://dev.to/craftzdog/lessons-learned-while-building-my-react-native-mobile-app-3080