GWTReact / gwt-react

GWT Java bindings for React
MIT License
91 stars 17 forks source link

Interop with non-gwt-components #8

Closed itd-sw closed 7 years ago

itd-sw commented 7 years ago

I tried to use this library to integrate an existing react component into gwt. For this I

Unfortunately, there is no jsConstructor for it in the class, probably because it is native.

Using React.create(MyComponent::new, props) doesn't work either, because ComponentConstructorFn::create returns void.

My current workaround is my own ComponentConstructorFn interface

@JsFunction
public interface ComponentConstructorFn<P extends BaseProps, S extends JsPlainObj, T extends Component<P,S>> {
    T create(P props);
}

and then another React class which takes this constructor function to call React.createComponent.

Is there currently a better way of doing this or are there any plans to support this use case?

pstockley commented 7 years ago

When you import an existing JS react component, you end up with the Component constructor defined on the Global Window object. If you use webpack instead of a UMD package, you may need to explicitly assign the constructor to the Window object. See gwt-react/dist/src/index-react-router.js as an example.

Once you have this setup, you can just simply define an interface to access the constructor. Take React router as an example


    @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "ReactRouter")
    public class ReactRouter {

        public static HistoryMechanism browserHistory;
        public static HistoryMechanism hashHistory;

        public static ComponentConstructorFn<RouterProps> Router;
        public static ComponentConstructorFn<RouteProps> Route;
        public static ComponentConstructorFn<RouteProps> IndexRoute;
        public static ComponentConstructorFn<RedirectProps> Redirect;
        public static ComponentConstructorFn<RedirectProps> IndexRedirect;
    }

Then you can create an element by using these constructor functions e.g.

React.createElement(ReactRouter.Router, new RouterProps()...)