HarmonyOS APP开发---“快讯通“资讯阅读App,需要用到这个库
HarmonyOS APP开发—"快讯通"资讯阅读App,需要用到这个库
做一个资讯阅读 App,信息流列表用 RN 原生渲染保证流畅,文章详情用 H5 渲染保证排版灵活。RN 和 Web 怎么协作?
@react-native-ohos/react-native-webview的 JS 注入 + 双向消息通信,让混合开发无缝衔接。
📦 仓库地址:https://gitcode.com/CPF-RN/rntpc_react-native-webview | 安装:
npm install @react-native-ohos/react-native-webview
写在前面
"快讯通"是一个资讯阅读 App,核心策略是混合开发:
- 信息流列表(RN 原生):列表滑动要 60fps 流畅,用 RN FlatList + FastImage
- 文章详情(H5):文章排版复杂(富文本、图片、视频嵌入、代码高亮),CMS 输出的是 HTML,用 H5 渲染最灵活
- 活动页/广告(H5):运营频繁改内容,H5 热更新方便
这就需要 RN 原生列表和 WebView 之间无缝协作:
- 用户在列表点击 → RN 导航到详情页 → WebView 加载文章 HTML
- 文章页内嵌的视频/链接 → 通过消息通信交给 RN 处理(原生播放器/原生浏览器)
- 暗色模式 → RN 通知 WebView 切换 CSS 主题
react-native-webview 的 postMessage / onMessage / injectJavaScript 三板斧,让 RN 和 Web 双向通信丝滑顺畅。
这篇文章聊什么
- 嵌入 H5 文章——WebView 加载 HTML + 注入暗色模式 CSS
- RN ↔ Web 通信——文章内链接点击交给 RN 处理
- 导航拦截——支付/授权类 URL 走原生页面
第一步:安装
npm install @react-native-ohos/react-native-webview
第二步:文章详情页——WebView 加载 H5
import { WebView, WebViewNavigation } from '@react-native-ohos/react-native-webview'
import { useRef, useEffect } from 'react'
function ArticleDetailPage({ article }: { article: { id: string; html: string } }) {
const webViewRef = useRef<WebView>(null)
// 页面加载完成后注入暗色模式 CSS
const injectDarkMode = () => {
webViewRef.current?.injectJavaScript(`
const style = document.createElement('style');
style.textContent = \`
body { background: #1a1a1a; color: #e0e0e0; }
h1, h2, h3 { color: #fff; }
a { color: #4ECDC4; }
img { filter: brightness(0.9); }
\`;
document.head.appendChild(style);
true;
`)
}
return (
<WebView
ref={webViewRef}
source={{ html: article.html }}
onLoadEnd={injectDarkMode} // 加载完成后注入 CSS
style={{ flex: 1 }}
onMessage={(e) => {
// 接收 Web 发来的消息(链接点击等)
const msg = JSON.parse(e.nativeEvent.data)
handleWebMessage(msg)
}}
onShouldStartLoadWithRequest={(request: WebViewNavigation) => {
// 拦截特定 URL,走原生处理
if (request.url.startsWith('mailto:') || request.url.startsWith('tel:')) {
// 交给系统处理
return false
}
return true
}}
/>
)
}
injectJavaScript 在页面加载完成后注入暗色 CSS——RN 通知 WebView 切换主题,不用改 H5 代码。
第三步:Web → RN 消息通信(链接点击)
文章 H5 内的链接点击,通过 postMessage 交给 RN 处理:
H5 端注入的 JS(在 injectJavaScript 里注入):
// 给所有 <a> 标签绑定点击事件
document.querySelectorAll('a').forEach((a) => {
a.addEventListener('click', (e) => {
e.preventDefault() // 阻止 WebView 内跳转
const url = a.href
// 发消息给 RN
window.ReactNativeWebView.postMessage(JSON.stringify({
type: 'link_click',
url: url,
}))
})
})
RN 端接收并处理:
function handleWebMessage(msg: { type: string; url: string }) {
switch (msg.type) {
case 'link_click':
if (msg.url.includes('youtube.com') || msg.url.includes('bilibili.com')) {
// 视频 → 用 RN 原生播放器打开
navigation.navigate('VideoPlayer', { url: msg.url })
} else {
// 外链 → 用系统浏览器打开
Linking.openURL(msg.url)
}
break
}
}
核心思路:WebView 不自行跳转 URL,所有链接通过 postMessage 交给 RN 决策——视频走原生播放器,外链走系统浏览器,保证体验一致性。
第四步:RN → Web 消息通信(滚动同步)
信息流列表的滚动进度同步给文章页,让 WebView 内的文章也跟随滚动:
// RN 向 Web 发消息
function syncScrollOffset(offset: number) {
webViewRef.current?.postMessage(JSON.stringify({
type: 'scroll_sync',
offset: offset,
}))
}
// 在 FlatList 的 onScroll 中调用
<FlatList
onScroll={(e) => {
syncScrollOffset(e.nativeEvent.contentOffset.y)
}}
/>
H5 端接收:
window.addEventListener('message', (e) => {
const msg = JSON.parse(e.data)
if (msg.type === 'scroll_sync') {
window.scrollTo(0, msg.offset)
}
})
为什么"快讯通"选了 WebView?
| 需求 | 纯 RN 渲染 | 混合 RN + WebView |
|---|---|---|
| 文章排版 | ❌ 富文本难处理 | ✅ H5 排版灵活 |
| 运营改活动 | ❌ 要发版 | ✅ H5 热更新 |
| 视频/外链 | WebView 内跳转 | ✅ 交给原生处理 |
| 暗色模式 | 全局改 | ✅ 注入 CSS |
| 性能 | 列表快 | ✅ 列表 RN + 详情 H5 |
总结
"快讯通"这个场景里,@react-native-ohos/react-native-webview 解决了三件事:
- H5 文章渲染——
source={{ html }}加载 CMS 输出的富文本 - RN ↔ Web 通信——链接点击
postMessage给 RN,视频/外链走原生 - 主题注入——
injectJavaScript注入暗色 CSS,不用改 H5 代码
如果你也在做资讯、电商、活动页等需要混合开发的 RN 鸿蒙应用,react-native-webview 是 RN 与 Web 协作的桥梁。
更多推荐



所有评论(0)