It seems WebView plays a similar role of web workers for react-native.
I am trying to offload heavy data fetch to a WebView but it seems very painful and could not find a fetch
example with WebView
.
So I have below JavaScript code with which I am trying to call the API.
When using the exact same code from a regular react-native class, the JSON response is perfectly fetched and parsed.
But when the same JavaScript code is injected into a WebView with injectJavaScript
method, the Content-Type
value causes the problem. (When I remove it, I see from the backend that the call is made but I can not get the JSON data at the frontend - WebView side-.)
It seems it is related to cors even though the API backend allows all cross-origin requests.
As a result, my questions are:
var l_headers = {
Accept: 'application/json',
'Content-Type': 'application/json'
};
var l_init = {
method: "POST",
headers: l_headers,
body: {}
};
fetch("http://172.20.10.12:8000/test", l_init).then(function (response) {
return response.json();
}).then(function (responseJson) {
alert('API called: ' + JSON.stringify(responseJson));
});
PS: One final handicap, please note that I am also using EXPO and not able to eject because of its benefits. That is why I can not use react-native-community's react-native-webview as of today. (It seems in future this will be adapted for EXPO).
Update
Following code snippet, I am fetching JSON through POST fetch and once fetched the response gets shown inside alert. Here is a working Snack Expo Link.
injectjs() {
let jsCode = `const bodyData = JSON.stringify({
title: 'foo',
body: 'bar',
userId: 1
});
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: bodyData,
}).then(response => response.text()).then(valueText => {
alert(JSON.stringify(valueText));
});`;
return jsCode;
}
render() {
return (
<View style={styles.container}>
<WebView
ref={webview => { this.webview = webview; }}
source={{
uri: "https://www.google.com"
}}
injectedJavaScript={this.injectjs()}
javaScriptEnabled = {true}
style={styles.webview}
/>
</View>
);
}
Old Answer
I usually use postMessage
in ReactNative WebView when I need to communicate between HTML and react native code.
postMessage(JSON.stringify(yourJson), '*');
document.addEventListener('message',(event) => {
eval(event, data)
}, false)
<WebView
ref={webview => { this.webview = webview; }}
source={anySource}
injectedJavaScript={script}
javaScriptEnabled = {true}
onMessage={this.onMessage}
onNavigationStateChange = {this.handleNavigation}
/>
onMessage = (e) => {
let { data } = e.nativeEvent; // data you will receive from html
}
this.webview.postMessage('YourMessage')
If postMessage
doesn't work in expo you can use onShouldStartLoadWithRequest
/ onNavigationStateChange
method instead.
handleNavigation = (event) => {
const url = event.url;
const sections = url.split('#');
if(sections.length > 1 && sections[1].indexOf('message=') != -1) {
const message = sections[1[.replace('message=', '');
//Do any action with message
return;
}
//Other navigation actions
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With