Skip to content

Conversation

@cbrevik
Copy link
Contributor

@cbrevik cbrevik commented May 30, 2017

Motivation

See discussion in #10946. The motivation is to make ReactWebViewManager more extensible.

Re-using logic from the ReactWebViewManager when implementing your own custom WebView is a pain since so much of the logic is set as private.

This PR makes for easier extension/overriding of behavior, and less duplication of code, since most of the methods/fields are set as protected instead.

I've also made some "create" methods for the WebView and WebViewBridge so they can more easily be overridden.

Test plan
The test plan is the same as the other PR (#10946). I've made an simple test app which extends RCTWebViewManager: https://github.com/cbrevik/overrideWebview

See CustomWebViewManager.java for a simple implementation.

CC @shergin (#10946 (comment))

For easier extension/overriding of behavior, and less duplication
of code
@facebook-github-bot facebook-github-bot added GH Review: review-needed CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. labels May 30, 2017
@shergin shergin self-requested a review May 31, 2017 01:45
@shergin shergin self-assigned this May 31, 2017
@cbrevik
Copy link
Contributor Author

cbrevik commented Jul 12, 2017

@shergin mind taking another look at this now that the iOS ViewManager PR has landed? (Thanks btw!)

Would love to get the ball rolling on #10946 again 😄

@facebook-github-bot facebook-github-bot added GH Review: accepted Import Started This pull request has been imported. This does not imply the PR has been approved. and removed GH Review: review-needed labels Jul 13, 2017
@facebook-github-bot
Copy link
Contributor

@shergin has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

facebook-github-bot pushed a commit that referenced this pull request Sep 19, 2017
Summary:
Opening a new PR for #10946 (see discussion there).

This PR builds upon #14775 (iOS ViewManager inheritance) and #14261 (more extensible Android WebView).

**Motivation**
When `WebView.android.js` and `WebView.ios.js` use `requireNativeComponent`, they are hard-coded to require `RCTWebView`. This means if you want to re-use the same JS-logic, but require a custom native WebView-implementation, you have to duplicate the entire JS-code files.

The same is true if you want to pass through any custom events or props, which you want to set on the custom native `WebView`.

What I'm trying to solve with this PR is to able to extend native WebView logic, and being able to re-use and extend existing WebView JS-logic.

This is done by adding a new `nativeConfig` prop on WebView. I've also moved the  extra `requireNativeComponent` config to `WebView.extraNativeComponentConfig` for easier re-use.

**Test plan**
jacobp100 has been kind enough to help me with docs for this new feature. So that is part of the PR and can be read for some information.

I've also created an example app which demonstrates how to use this functionality: https://github.com/cbrevik/webview-native-config-example

If you've implemented the native side as in the example repo above, it should be fairly easy to use from JavaScript like this:
```javascript
import React, { Component, PropTypes } from 'react';
import { WebView, requireNativeComponent, NativeModules } from 'react-native';
const { CustomWebViewManager } = NativeModules;

export default class CustomWebView extends Component {
  static propTypes = {
    ...WebView.propTypes,
    finalUrl: PropTypes.string,
    onNavigationCompleted: PropTypes.func,
  };

  _onNavigationCompleted = (event) => {
    const { onNavigationCompleted } = this.props;
    onNavigationCompleted && onNavigationCompleted(event);
  }

  render() {
    return (
      <WebView
        {...this.props}
        nativeConfig={{
          component: RCTCustomWebView,
          props: {
            finalUrl: this.props.finalUrl,
            onNavigationCompleted: this._onNavigationCompleted,
          },
          viewManager: CustomWebViewManager
        }}
      />
    );
  }
}

const RCTCustomWebView = requireNativeComponent(
  'RCTCustomWebView',
  CustomWebView,
  WebView.extraNativeComponentConfig
);
```

As you see, you require the custom native implementation at the bottom, and send in that along with any custom props with the `nativeConfig` prop on the `WebView`. You also send in the `viewManager` since iOS requires that for `startLoadWithResult`.

**Discussion**
As noted in the original PR, this could in principle be done with more React Native components, to make it easier for the community to re-use and extend native components.
Closes #15016

Differential Revision: D5701280

Pulled By: hramos

fbshipit-source-id: 6c3702654339b037ee81d190c623b8857550e972
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Import Started This pull request has been imported. This does not imply the PR has been approved.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants