This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.

编辑富文本

编辑页面

了解在 React Native 中预览和编辑富文本的当前方法。


Many apps need to let users enter text. For example, if you want to build a messaging or social media app, you’ll likely rely heavily on text input. React Native includes the <TextInput> component out of the box, which makes this easy in many simple scenarios.

However, sometimes you need a bit more flexibility. Think of long social media posts, note-taking apps, or document editors. Ideally, you’d want support for different text styles, lists, headings, inline images, and more. This is called a rich text editor, and it’s a hard problem to solve well everywhere, including in React Native.

At the moment, there isn’t a default solution in the React Native ecosystem. However, this guide will explore some options and promising approaches, each with its own trade-offs.

Watch: How to build a rich text editor with DOM components
Watch: How to build a rich text editor with DOM components

Use Expo DOM components to render a web-based editor in a native app, enabling a rich text editor in React Native.

渲染富文本

显示富文本有很多不错的选择:

  • 对于 markdown 内容,你可以使用 markdown 渲染器,例如 react-native-enriched-markdown 或其他类似工具。

  • 对于 HTML 内容,你可以使用 @expo/html-elements 或 WebView(react-native-webview)。

  • 如果想要自定义格式并获得更多控制权,你可以利用嵌套的 <Text> 组件来渲染样式和布局。

    <TextInput> <Text> <Text style={{ fontWeight: 900 }}>Some bold text</Text>Some regular text </Text> </TextInput>
  • 你也可以使用 Expo Modules API 结合第三方库,例如 Android 上的 Markwon 和 iOS 上的 AttributedString,编写一个使用原生平台基础组件的自定义渲染组件。

编辑富文本的方法

要让富文本渲染正常工作,有几种不同的方法。不过,它们都有各自的限制。

基于 WebView 的编辑器

大多数 React Native UI 组件封装的是原生平台基础组件,因此速度快、性能好,并且因此带有原生体验。而基于 WebView 的富文本编辑器采用的是不同的方法。

它们会把一个原本为 Web 构建的现有富文本编辑器,通过 JavaScript 包装在 react-native-webview 中。它可以在所有平台上运行(Android、iOS、Web),并且能利用 Web 平台上已有的流行富文本编辑器,但会带来性能和用户体验上的损耗。

你将无法在编辑器内部使用原生 UI 组件。诸如提及功能或图片嵌入之类特性的任何实现,都会重复造轮子,并且需要投入大量精力来实现。

现有的基于 WebView 的 React Native 库

目前已有一些 React Native 库可以支持富文本编辑。如果你只需要一个基础的富文本编辑器,配置较少,而且对性能或用户体验没有严格要求,那么这些是最容易上手的选择:

自定义基于 WebView 的编辑器

如果你需要更强的可配置性,可以基于现有的仅 Web 编辑器构建一个类似的库。不过,你需要自己处理消息传递和 Web 端实现。这会让你获得底层编辑器提供的所有能力,并允许你实现更多功能。

你需要使用消息传递来在 WebView 与外部之间传递文本和 onChange 事件。由于富文本通常会变得很长,最好将其建模为非受控组件,以避免每次按键时都产生卡顿。另外,如果你能避免在每次按键时序列化并发送整个状态,也能提升性能。

基于 React Native TextInput 构建

在这一部分,我们来讨论是否有可能为通用场景提供一个功能完整的富文本输入框。

React Native 允许嵌套 <Text> 组件,并且允许它们作为 <TextInput> 的子元素来渲染和编辑样式化文本。它与新的 React Native 架构是同步的(onChange 事件会在文本输入字段中输入新字符后立即触发)。

不幸的是,<TextInput> 组件是围绕普通文本设计的,它在 onTextChange 回调中只返回一个字符串。这是一个很大的限制。

下面是一个快速示例。先渲染一个包含如下粗体文本的文本输入:

<TextInput> <Text> {/* 以下内容将以这种格式渲染粗体文本:**aa**aa */} <Text style={{ fontWeight: 900 }}>aa</Text>aa </Text> </TextInput>

然后,向文本输入中追加第五个字母 a。光标的位置应决定这个新字母是否属于粗体字符串的一部分。不幸的是,回调只会返回 aaaaa

还有一个额外的 onSelectionChange 属性可以用来获取这类信息。不过,这会让任务变得更加困难。插入额外字符(例如用于列表或项目符号的换行)也会使选区不同步。

已经有一些尝试构建这种编辑器的项目,例如 markdown-editor(未积极维护)和 rn-text-editor(测试版),但目前没有广泛使用的包。

带可见样式标记的 Markdown 编辑器

如果使用 markdown 来设置文本样式就能满足你的需求,那么你可以在编辑时将 markdown 渲染到一个单独的、不可编辑的视图中。使用任何 markdown 渲染器自己实现都不复杂。你也可以使用第三方库,例如 react-native-markdown-editor

这种编辑体验适合高级用户或编程/技术类应用。你也可以探索在选中的文本块中渲染富文本,同时只显示 markdown,或者其他混合方案。

原生编辑器

你可以使用封装为 React Native 模块的 Android 或 iOS 原生富文本编辑器。可选项有:

你也可以使用 Expo Modules API 封装任何原生富文本编辑器,但如果你在不同平台上使用不同的编辑器,就需要统一它们的 API 和输入格式。

目前也有人在努力将 lexical 编辑器移植到 Android 和 iOS,并提供 React Native 封装,在此跟踪进展

总结

虽然展示富文本有很多很好的选择,但在 React Native 中进行富文本编辑并没有一种通用的完美方案。也没有一种在大多数使用场景下都足够好的流行方案。还需要社区进一步贡献,以改进现有解决方案或添加新的方案。

目前,你需要在更复杂但功能更多、可能更难维护的原生编辑器,与基于 react-native 原语构建的编辑器之间仔细做出选择。这取决于这个功能对你的应用有多核心、你在编辑器中需要多少功能,以及你愿意投入多少精力去把它做完整。