编辑富文本

编辑

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


许多应用程序需要允许用户输入文本。例如,如果您想构建一个消息或社交媒体应用,您可能会在文本输入方面依赖很大。React Native 有一个内置的 <TextInput> 组件,可以在许多简单情况下实现这一点,几乎不需要任何努力。

然而,有时您需要更灵活一些。想想长的社交媒体帖子、笔记应用或文档编辑器。理想情况下,您需要允许不同的文本样式、列表、标题、嵌入图片等。这被称为富文本编辑器,这是一个在任何地方都难以解决的问题,包括在 React Native 中。

当前在 React Native 生态系统中没有默认的解决方案。然而,本指南探讨了一些选项和有前景的方法,每种方法都有其自身的权衡。

观看:如何使用 DOM 组件实现富文本编辑器
观看:如何使用 DOM 组件实现富文本编辑器

渲染富文本

有很多良好的选项可以显示富文本:

  • 对于 markdown 内容,您可以使用 markdown 渲染器,例如 react-native-markdown-display 或其他。

  • 对于 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 平台上可用的流行富文本编辑器,但它存在性能和 UX 的些许损失。

您将无法在编辑器内部使用原生 UI 组件。实现提及或图片嵌入等功能的任何实现都将重复功能,并需要大量的努力进行实现。

现有的基于 WebView 的 React Native 库

有一些现有的 React Native 库可以允许富文本编辑。如果您需要一个具有有限配置的基本富文本编辑器,并且没有严格的性能或 UX 要求,这是最简单的选项:

自定义基于 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 和输入格式。

富文本通常使用 抽象语法树 表示。例如,一个项目符号列表可以是类型为 bulleted-list 的节点,其中有多个类型为 list-item 的子节点。您可以将 HTML 和 markdown 转换为适当的 AST 格式。

还有一个努力将 lexical 编辑器移植到 Android 和 iOS,并提供一个 React Native 包装器 可以在这里跟踪

总结

虽然有许多很好的选项来显示富文本,但在 React Native 中没有一种适合所有情况的富文本编辑解决方案。没有一个流行的解决方案可以满足大多数用例。社区的进一步贡献对于改善现有解决方案或添加新方案是必要的。

目前,您需要仔细选择在功能上更复杂的原生编辑器,这提供更多功能但可能更难维护,或基于 React Native 原语构建的编辑器。这取决于该功能在您的应用中有多核心、您在编辑器中需要多少功能以及您愿意花多少精力来构建它。