|  | @@ -8,6 +8,10 @@ _This guide is currently a work in progress._
 | 
	
		
			
			| 8 | 8 |  
 | 
	
		
			
			| 9 | 9 |  - [Basic Inline HTML](Guide.md#basic-inline-html)
 | 
	
		
			
			| 10 | 10 |  - [Basic URL Source](Guide.md#basic-url-source)
 | 
	
		
			
			|  | 11 | +- [Controlling navigation state changes](Guide.md#controlling-navigation-state-changes)
 | 
	
		
			
			|  | 12 | +- [Add support for File Upload](Guide.md#add-support-for-file-upload)
 | 
	
		
			
			|  | 13 | +- [Add support for File Download](Guide.md#add-support-for-file-download)
 | 
	
		
			
			|  | 14 | +- [Communicating between JS and Native](Guide.md#communicating-between-js-and-native)
 | 
	
		
			
			| 11 | 15 |  
 | 
	
		
			
			| 12 | 16 |  ### Basic inline HTML
 | 
	
		
			
			| 13 | 17 |  
 | 
	
	
		
			
			|  | @@ -180,6 +184,7 @@ Save to gallery:
 | 
	
		
			
			| 180 | 184 |  ##### Android
 | 
	
		
			
			| 181 | 185 |  
 | 
	
		
			
			| 182 | 186 |  Add permission in AndroidManifest.xml:
 | 
	
		
			
			|  | 187 | +
 | 
	
		
			
			| 183 | 188 |  ```xml
 | 
	
		
			
			| 184 | 189 |  <manifest ...>
 | 
	
		
			
			| 185 | 190 |    ......
 | 
	
	
		
			
			|  | @@ -190,3 +195,144 @@ Add permission in AndroidManifest.xml:
 | 
	
		
			
			| 190 | 195 |    ......
 | 
	
		
			
			| 191 | 196 |  </manifest>
 | 
	
		
			
			| 192 | 197 |  ```
 | 
	
		
			
			|  | 198 | +
 | 
	
		
			
			|  | 199 | +### Communicating between JS and Native
 | 
	
		
			
			|  | 200 | +
 | 
	
		
			
			|  | 201 | +You will often find yourself wanting to send messages to the web pages loaded by your webviews and also receiving messages back from those web pages.
 | 
	
		
			
			|  | 202 | +
 | 
	
		
			
			|  | 203 | +To accomplish this, React Native WebView exposes three different options:
 | 
	
		
			
			|  | 204 | +
 | 
	
		
			
			|  | 205 | +1. React Native -> Web: The `injectedJavaScript` prop
 | 
	
		
			
			|  | 206 | +2. React Native -> Web: The `injectJavaScript` method
 | 
	
		
			
			|  | 207 | +3. Web -> React Native: The `postMessage` method and `onMessage` prop
 | 
	
		
			
			|  | 208 | +
 | 
	
		
			
			|  | 209 | +#### The `injectedJavaScript` prop
 | 
	
		
			
			|  | 210 | +
 | 
	
		
			
			|  | 211 | +This is a script that runs immediately after the web page loads for the first time. It only runs once, even if the page is reloaded or navigated away.
 | 
	
		
			
			|  | 212 | +
 | 
	
		
			
			|  | 213 | +```jsx
 | 
	
		
			
			|  | 214 | +import React, { Component } from "react";
 | 
	
		
			
			|  | 215 | +import { View } from "react-native";
 | 
	
		
			
			|  | 216 | +import { WebView } from "react-native-webview";
 | 
	
		
			
			|  | 217 | +
 | 
	
		
			
			|  | 218 | +export default class App extends Component {
 | 
	
		
			
			|  | 219 | +  render() {
 | 
	
		
			
			|  | 220 | +    const runFirst = `
 | 
	
		
			
			|  | 221 | +      document.body.style.backgroundColor = 'red';
 | 
	
		
			
			|  | 222 | +      setTimeout(function() { window.alert('hi') }, 2000);
 | 
	
		
			
			|  | 223 | +      true; // note: this is required, or you'll sometimes get silent failures
 | 
	
		
			
			|  | 224 | +    `;
 | 
	
		
			
			|  | 225 | +    return (
 | 
	
		
			
			|  | 226 | +      <View style={{ flex: 1 }}>
 | 
	
		
			
			|  | 227 | +        <WebView
 | 
	
		
			
			|  | 228 | +          source={{
 | 
	
		
			
			|  | 229 | +            uri:
 | 
	
		
			
			|  | 230 | +              "https://github.com/react-native-community/react-native-webview"
 | 
	
		
			
			|  | 231 | +          }}
 | 
	
		
			
			|  | 232 | +          injectedJavaScript={runFirst}
 | 
	
		
			
			|  | 233 | +        />
 | 
	
		
			
			|  | 234 | +      </View>
 | 
	
		
			
			|  | 235 | +    );
 | 
	
		
			
			|  | 236 | +  }
 | 
	
		
			
			|  | 237 | +}
 | 
	
		
			
			|  | 238 | +```
 | 
	
		
			
			|  | 239 | +
 | 
	
		
			
			|  | 240 | +This runs the JavaScript in the `runFirst` string once the page is loaded. In this case, you can see that both the body style was changed to red and the alert showed up after 2 seconds.
 | 
	
		
			
			|  | 241 | +
 | 
	
		
			
			|  | 242 | +<img alt="screenshot of Github repo" width="200" src="https://user-images.githubusercontent.com/1479215/53609254-e5dc9c00-3b7a-11e9-9118-bc4e520ce6ca.png" />
 | 
	
		
			
			|  | 243 | +
 | 
	
		
			
			|  | 244 | +*Under the hood*
 | 
	
		
			
			|  | 245 | +
 | 
	
		
			
			|  | 246 | +> On iOS, `injectedJavaScript` runs a method on WKWebView called `evaluateJavaScript:completionHandler:`
 | 
	
		
			
			|  | 247 | +> On Android, `injectedJavaScript` runs a method on the Android WebView called `evaluateJavascriptWithFallback`
 | 
	
		
			
			|  | 248 | +
 | 
	
		
			
			|  | 249 | +#### The `injectJavaScript` method
 | 
	
		
			
			|  | 250 | +
 | 
	
		
			
			|  | 251 | +While convenient, the downside to the previously mentioned `injectedJavaScript` prop is that it only runs once. That's why we also expose a method on the webview ref called `injectJavaScript` (note the slightly different name!).
 | 
	
		
			
			|  | 252 | +
 | 
	
		
			
			|  | 253 | +```jsx
 | 
	
		
			
			|  | 254 | +import React, { Component } from "react";
 | 
	
		
			
			|  | 255 | +import { View } from "react-native";
 | 
	
		
			
			|  | 256 | +import { WebView } from "react-native-webview";
 | 
	
		
			
			|  | 257 | +
 | 
	
		
			
			|  | 258 | +export default class App extends Component {
 | 
	
		
			
			|  | 259 | +  render() {
 | 
	
		
			
			|  | 260 | +    const run = `
 | 
	
		
			
			|  | 261 | +      document.body.style.backgroundColor = 'blue';
 | 
	
		
			
			|  | 262 | +      true;
 | 
	
		
			
			|  | 263 | +    `;
 | 
	
		
			
			|  | 264 | +
 | 
	
		
			
			|  | 265 | +    setTimeout(() => {
 | 
	
		
			
			|  | 266 | +      this.webref.injectJavaScript(run);
 | 
	
		
			
			|  | 267 | +    }, 3000);
 | 
	
		
			
			|  | 268 | +
 | 
	
		
			
			|  | 269 | +    return (
 | 
	
		
			
			|  | 270 | +      <View style={{ flex: 1 }}>
 | 
	
		
			
			|  | 271 | +        <WebView
 | 
	
		
			
			|  | 272 | +          ref={r => (this.webref = r)}
 | 
	
		
			
			|  | 273 | +          source={{
 | 
	
		
			
			|  | 274 | +            uri:
 | 
	
		
			
			|  | 275 | +              "https://github.com/react-native-community/react-native-webview"
 | 
	
		
			
			|  | 276 | +          }}
 | 
	
		
			
			|  | 277 | +        />
 | 
	
		
			
			|  | 278 | +      </View>
 | 
	
		
			
			|  | 279 | +    );
 | 
	
		
			
			|  | 280 | +  }
 | 
	
		
			
			|  | 281 | +}
 | 
	
		
			
			|  | 282 | +```
 | 
	
		
			
			|  | 283 | +
 | 
	
		
			
			|  | 284 | +After 3 seconds, this code turns the background blue:
 | 
	
		
			
			|  | 285 | +
 | 
	
		
			
			|  | 286 | +<img alt="Screenshot of app showing injected javascript" width="200" src="https://user-images.githubusercontent.com/1479215/53670433-93a98280-3c2f-11e9-85a5-0e4650993817.png" />
 | 
	
		
			
			|  | 287 | +
 | 
	
		
			
			|  | 288 | +*Under the hood*
 | 
	
		
			
			|  | 289 | +
 | 
	
		
			
			|  | 290 | +> On iOS, `injectJavaScript` calls WKWebView's `evaluateJS:andThen:`
 | 
	
		
			
			|  | 291 | +> On Android, `injectJavaScript` calls Android WebView's `evaluateJavascriptWithFallback` method
 | 
	
		
			
			|  | 292 | +
 | 
	
		
			
			|  | 293 | +#### The `window.ReactNativeWebView.postMessage` method and `onMessage` prop
 | 
	
		
			
			|  | 294 | +
 | 
	
		
			
			|  | 295 | +Being able to send JavaScript to the web page is great, but what about when the web page wants to communicate back to your React Native code? This where `window.ReactNativeWebView.postMessage` and the `onMessage` prop come in.
 | 
	
		
			
			|  | 296 | +
 | 
	
		
			
			|  | 297 | +You _must_ set `onMessage` or the `window.ReactNativeWebView.postMessage` method will not be injected into the web page.
 | 
	
		
			
			|  | 298 | +
 | 
	
		
			
			|  | 299 | +`window.ReactNativeWebView.postMessage` only accepts one argument which must be a string.
 | 
	
		
			
			|  | 300 | +
 | 
	
		
			
			|  | 301 | +```jsx
 | 
	
		
			
			|  | 302 | +import React, { Component } from "react";
 | 
	
		
			
			|  | 303 | +import { View } from "react-native";
 | 
	
		
			
			|  | 304 | +import { WebView } from "react-native-webview";
 | 
	
		
			
			|  | 305 | +
 | 
	
		
			
			|  | 306 | +export default class App extends Component {
 | 
	
		
			
			|  | 307 | +  render() {
 | 
	
		
			
			|  | 308 | +    const html = `
 | 
	
		
			
			|  | 309 | +      <html>
 | 
	
		
			
			|  | 310 | +      <head></head>
 | 
	
		
			
			|  | 311 | +      <body>
 | 
	
		
			
			|  | 312 | +        <script>
 | 
	
		
			
			|  | 313 | +          setTimeout(function () {
 | 
	
		
			
			|  | 314 | +            window.ReactNativeWebView.postMessage("Hello!")
 | 
	
		
			
			|  | 315 | +          }, 2000)
 | 
	
		
			
			|  | 316 | +        </script>
 | 
	
		
			
			|  | 317 | +      </body>
 | 
	
		
			
			|  | 318 | +      </html>
 | 
	
		
			
			|  | 319 | +    `;
 | 
	
		
			
			|  | 320 | +
 | 
	
		
			
			|  | 321 | +    return (
 | 
	
		
			
			|  | 322 | +      <View style={{ flex: 1 }}>
 | 
	
		
			
			|  | 323 | +        <WebView
 | 
	
		
			
			|  | 324 | +          source={{ html }}
 | 
	
		
			
			|  | 325 | +          onMessage={event => {
 | 
	
		
			
			|  | 326 | +            alert(event.nativeEvent.data);
 | 
	
		
			
			|  | 327 | +          }}
 | 
	
		
			
			|  | 328 | +        />
 | 
	
		
			
			|  | 329 | +      </View>
 | 
	
		
			
			|  | 330 | +    );
 | 
	
		
			
			|  | 331 | +  }
 | 
	
		
			
			|  | 332 | +}
 | 
	
		
			
			|  | 333 | +```
 | 
	
		
			
			|  | 334 | +
 | 
	
		
			
			|  | 335 | +This code will result in this alert:
 | 
	
		
			
			|  | 336 | +
 | 
	
		
			
			|  | 337 | +<img alt="Alert showing communication from web page to React Native" width="200" src="https://user-images.githubusercontent.com/1479215/53671269-7e822300-3c32-11e9-9937-7ddc34ba8af3.png" />
 | 
	
		
			
			|  | 338 | +
 |