I assume this is needed in case you are loading a page which is slow to load over the network. In my case I was not receiving events on the document object.
4.1 KiB
React Native WebView Javascript Bridge
This is an attempt to create a Javascript Bridge between React Native and Webview.
In order for me to port WebViewJavascriptBridge to React Native, I had to extends WebView component provided by Facebook. I wanted a feature like
sendandonMessageto communicate between React-Native Components and Web View content.
Installation
In order to use this frame work you have to do couple of simple step.
- run
npm install react-native-webview-bridge - go to
Project Navigatortab in xcode - right click on
Libraries - select
Add Files to ...option - navigate to
node_modules/react-native-webview-bridgeand addWebViewBridgefolder - clean compile to make sure your project can compile and build.
Usage
In order for WebView's javascript communicates to React-Native, you have to add couple of function into your existing web app.
<html>
<head>
<title>My Awesome Web App</title>
</head>
<body>
<script>
var myBridge = null;
//whenever react native component sends a message to WebView,
//this callback is called.
function onMessage(message) {
console.log('This message coming from react-native', message);
}
//if the bridge is established, you can use this function to send
//a message to react native code.
function send(message) {
if (myBridge) {
myBridge.send(message);
}
}
//this function register a callback into inject code in webview
//and once the bridge is ready, it will pass the bridge ref to the
//callback
function connectWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
} else {
window.addEventListener('WebViewJavascriptBridgeReady', function() {
callback(WebViewJavascriptBridge);
}, false)
}
}
connectWebViewJavascriptBridge(function (bridge) {
myBridge = bridge;
bridge.init(onMessage);
//you can call any other function here to notify that
//bridge is connected and ready to be used.
});
</script>
</body>
</html>
on React Native side, instead of using WebView component, use the following one.
var React = require('react-native');
var WebViewBridge = require('react-native-webview-bridge');
var {
Component
} = React;
var WEBVIEW_REF = 'my_webview';
class MyAwesomeView extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
var webviewRef = this.refs[WEBVIEW_REF];
webviewRef.onMessage(function (message) {
console.log("This message coming from web view", message);
setTimeout(function () {
webviewRef.send("Hello from react-native");
}, 1000);
});
}
render() {
return (
<WebViewBridge
ref={WEBVIEW_REF}
url="http://<my awesome project url>"
style={{flex: 1}}
/>
);
}
}
WebViewBridge
WebViewBridge extends 'WebView' so you can have all the available feature of WebView. I have just added 2 methods
send(message )
send any message from react-native to web view
onMessage(callback )
any messages coming from web view will invoke callback with an argument message. Message can be any types.
eval(value )
it will execute javascript string and eval it inside the web view. It is useful if you need to set some global variable before your script is executing. For example set JWT token as a global variable.
Common Problems
If you are rendering WebViewBridge make sure that you also keep registering to the callback.
registerCallback() {
var webViewBridge = this.refs[WEBVIEW_REF];
webViewBridge.onMessage(this.onBridgeMessage.bind(this));
}
I used that method inside my component and I keep calling it inside componentDidUpdate.
Thanks
Thanks to @marcuswestin for amazing WebViewJavascriptBridge library.