Hybrid开发中如何在React页面里调用原生UI组件?

Tr° 子格 阅读 13

我最近在做Hybrid App,用React写H5页面,但有个需求是要调用原生的弹窗(比如iOS的UIAlertController),而不是用JS的alert。我查了下资料说可以通过JSBridge来通信,但试了几次都没成功,原生那边收不到消息。

我在React里是这样写的:

const showNativeAlert = () => {
  if (window.ReactNativeWebView) {
    window.ReactNativeWebView.postMessage(JSON.stringify({
      type: 'showAlert',
      title: '提示',
      message: '这是原生弹窗'
    }));
  }
};

但点击按钮后完全没反应,控制台也没报错。是不是我漏了什么配置?或者原生那边需要额外注册监听?

我来解答 赞 4 收藏
二维码
手机扫码查看
1 条解答
程序员文瑞
你这个问题,一眼看过去就知道是典型的JSBridge对接不上。你用的window.ReactNativeWebView这个对象是React Native WebView组件专用的,如果你不是在RN环境里跑,这个对象根本就不存在,当然没反应。

先搞清楚你的场景。如果是原生iOS/Android项目里套了个WebView,那你得自己实现JSBridge,不能直接用RN的那套。

说下原生端怎么搞。

iOS端用WKWebView的话,需要注入一个messageHandler。原生代码里这样写:

let contentController = WKUserContentController()
contentController.add(self, name: "nativeBridge")

let config = WKWebViewConfiguration()
config.userContentController = contentController

// 然后在WKScriptMessageHandler代理方法里接收
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "nativeBridge" {
if let body = message.body as? String {
// 解析JSON,处理showAlert逻辑
print("收到H5消息: (body)")
}
}
}


前端调用方式改成这样:

const showNativeAlert = () => {
const data = JSON.stringify({
type: 'showAlert',
title: '提示',
message: '这是原生弹窗'
});

// iOS调用方式
if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.nativeBridge) {
window.webkit.messageHandlers.nativeBridge.postMessage(data);
}
// Android调用方式
else if (window.AndroidBridge) {
window.AndroidBridge.postMessage(data);
}
};


Android端用WebView的JavascriptInterface:

webView.addJavascriptInterface(new Object() {
@JavascriptInterface
public void postMessage(String data) {
// 解析data,处理showAlert逻辑
Log.d("JSBridge", "收到H5消息: " + data);
}
}, "AndroidBridge");


还有个常见坑,Android这边记得开启JS支持:

webView.getSettings().setJavaScriptEnabled(true);


你可以在前端先打个log,看看window.webkit或者window.AndroidBridge到底存不存在。如果都不存在,说明原生端没配置好注入,找你们iOS和Android同事确认下。这种跨端通信的问题,前端和原生两边都得配合,单方面调试很难搞。
点赞 1
2026-02-28 21:02