private ClassicComponentClass<BaseProps> customComponent;
public void onModuleLoad() {
customComponent = React.createClass(new CustomComponent());
HTMLProps props = Props.newHTML();
props.setDefaultValue("Test");
DOMElement<HTMLProps> div =
React.createElement("div", props,
React.createElement("div", null),
React.createElement(customComponent, null),
React.createElement("div", null, "An example")
);
ReactDOM.render(div, Document.get().getElementById("mainCont"));
}
@JsType(namespace = JsPackage.GLOBAL, name="CustomComponent")
public class CustomComponent {
@JsMethod
public ReactElement<?> render() {
return React.createElement("div", null, "It works");
}
}
This works fine for intrinsic React components. The problem is defining custom components. The React.createClass function needs to take a plain javascript object with certain methods defined (render, lifecyle methods etc). If I pass a Java object marked as JsType, this doesn't work because the render method needs to be defined on the top level object. The code puts it on a different prototype which doesn't work because React does the following:
for (var name in spec) { if (!spec.hasOwnProperty(name)) { --Isn't true for render continue; }
Is there some way to achieve what I want with JsInterop? I tried extending another base class marked with isNative=true. However, this results in a runtime error when trying to construct an object of that type.
I am going to try a real hack with a JSNI method that constructs an object given the various
methods as parameters.
--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/1dfb2508-9f88-4ecc-a30f-51814c496082%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/CADcXZMycRicPkGNiPHab-d9ZAL4afWkVkwaU7%2Bu649AHPQX6Xw%40mail.gmail.com.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/1dfb2508-9f88-4ecc-a30f-51814c496082%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/1dfb2508-9f88-4ecc-a30f-51814c496082%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/CADcXZMycRicPkGNiPHab-d9ZAL4afWkVkwaU7%2Bu649AHPQX6Xw%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/186118a0-e595-47ea-a98a-24ca8603535f%40googlegroups.com.
@JsType
public class CustomComponent {
public static ReactElement<?> render() {
return React.createElement("div", null, "It works");
}
static final public native JavaScriptObject makeSpec() /*-{
return { render : $entry(@com.ocs.react.client.CustomComponent::render()) };
}-*/;
}
public class ReactMain implements EntryPoint {
@Override
public void onModuleLoad() {
ClassicComponentClass<BaseProps> customComponent = React.createClass(CustomComponent.makeSpec());
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/1dfb2508-9f88-4ecc-a30f-51814c496082%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/CADcXZMycRicPkGNiPHab-d9ZAL4afWkVkwaU7%2Bu649AHPQX6Xw%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/186118a0-e595-47ea-a98a-24ca8603535f%40googlegroups.com.To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-co...@googlegroups.com.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/1dfb2508-9f88-4ecc-a30f-51814c496082%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/CADcXZMycRicPkGNiPHab-d9ZAL4afWkVkwaU7%2Bu649AHPQX6Xw%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/1dfb2508-9f88-4ecc-a30f-51814c496082%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/CADcXZMycRicPkGNiPHab-d9ZAL4afWkVkwaU7%2Bu649AHPQX6Xw%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.
import java.util.function.Function;
@JsType(namespace = JsPackage.GLOBAL, name="CustomComponent")
public class CustomComponent extends React.Component {
public BaseProps props;
public ReactElement<?> render() {
return React.createElement("div", null, "Classic Comp works");
}
// 1) Just returns undefined
@JsProperty(namespace = JsPackage.GLOBAL)
public static native Function getCustomComponent();
// 2) Crashes compiler with internal error
public static native Function constructor() /*-{
return @com.ocs.react.client.CustomComponent::new(*);
}-*/;
// 3) Crashes compiler with internal error
public static native Function constructor(String qualifiedJsTypeName) /*-{
@JsType(isNative = true)
private static class FuncProps extends BaseProps {
public String aProp;
}
static final public native FuncProps makeFuncProps() /*-{
return {};
}-*/;
@Override
public void onModuleLoad() {
ClassicComponentClass<BaseProps> customClassicComponent = React.createClass(CustomClassicComponent.makeSpec());
FunctionalComponent<FuncProps> funcComp =
(props)->{return React.createElement("div", null, "Functional component works " + props.aProp);};
FuncProps fProps = makeFuncProps();
fProps.aProp = "Its a prop";
DOMElement<HTMLProps> div =
React.createElement("div", Props.HTML()._defaultValue("ss")._accept("y"),
React.createElement("div", null,
React.createElement(funcComp, fProps)),
React.createElement(customClassicComponent, null),
React.createElement("div", null, "An example")
);
ReactDOM.render(div, Document.get().getElementById("mainCont"));
}
I didn't have any success with any of the methods you presented. See belowimport java.util.function.Function;
@JsType(namespace = JsPackage.GLOBAL, name="CustomComponent")
public class CustomComponent extends React.Component {
public BaseProps props;
public ReactElement<?> render() {
return React.createElement("div", null, "Classic Comp works");
}
// 1) Just returns undefined
@JsProperty(namespace = JsPackage.GLOBAL)
public static native Function getCustomComponent();
// 2) Crashes compiler with internal error
public static native Function constructor() /*-{
return @com.ocs.react.client.CustomComponent::new(*);
}-*/;
// 3) Crashes compiler with internal error
public static native Function constructor(String qualifiedJsTypeName) /*-{
var cur = $wnd;
var parts = namespace.split('.');
for (var part; parts.length && (part = parts.shift());) {
cur = cur[part];
}
return cur;
}-*/;
}
--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/a52830d0-c2af-4660-b706-b9cc1d7123dd%40googlegroups.com.
I have made a bit more progress. I managed to get functional components working.@JsType(isNative = true)
private static class FuncProps extends BaseProps {
public String aProp;
}
static final public native FuncProps makeFuncProps() /*-{
return {};
}-*/;
@Override
public void onModuleLoad() {
ClassicComponentClass<BaseProps> customClassicComponent = React.createClass(CustomClassicComponent.makeSpec());
FunctionalComponent<FuncProps> funcComp =
(props)->{return React.createElement("div", null, "Functional component works " + props.aProp);};
FuncProps fProps = makeFuncProps();
fProps.aProp = "Its a prop";
DOMElement<HTMLProps> div =
React.createElement("div", Props.HTML()._defaultValue("ss")._accept("y"),
React.createElement("div", null,
React.createElement(funcComp, fProps)),
React.createElement(customClassicComponent, null),
React.createElement("div", null, "An example")
);
ReactDOM.render(div, Document.get().getElementById("mainCont"));
}So far no luck with ES6 based components. Javascript object literals are a real pain to deal with in Java at the moment. I would like to be able to do "new FuncProps()" but it fails at runtime.
So I have to resort to using JSNI to create the object. Having some sort of fluent interface like I defined for HTML props is about as close as you will get to the convenience of object literals in java. I could define a very generic javascript object like a map. This would be flexible but not very type safe.
--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/0112d192-3aa1-4e0d-87ad-72ab2c862bc9%40googlegroups.com.
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
private static class FuncProps extends BaseProps {
public String aProp;
}
Now makes new FuncProps() work, which is great.
public class JSFunction extends JavaScriptObject {
protected JSFunction() {};
}
@JsType(namespace = JsPackage.GLOBAL, name="CustomComponent")
public class CustomComponent {
// 1) Still Just returns undefined
@JsProperty(namespace = JsPackage.GLOBAL)
public static native JSFunction getCustomComponent();
// 2) Still crashes compiler with internal error
public static native JSFunction constructor() /*-{
return @com.ocs.react.client.CustomComponent::new(*);
}-*/;
// 3) Still crashes compiler with internal error
public static native JSFunction constructor(String qualifiedJsTypeName) /*-{
var cur = $wnd;
var parts = namespace.split('.');
for (var part; parts.length && (part = parts.shift());) {
cur = cur[part];
}
return cur;
}-*/;
}
I am running the latest snapshot build as of a couple of days ago and starting SD mode withRunning CodeServer with parameters: [-noprecompile, -port, 9876, -sourceLevel, 1.8, -bindAddress, 127.0.0.1, -launcherDir, /Users/paul/Library/Caches/IntelliJIdea15/gwt/gwt_react.da4c73b3/gwt_react.284d7c82/run/www, -logLevel, INFO, -generateJsInteropExports, -style, OBFUSCATED, com.ocs.react.React]I changed the Class to the following as suggested but it still doesn't workpublic class JSFunction extends JavaScriptObject {
protected JSFunction() {};
}@JsType(namespace = JsPackage.GLOBAL, name="CustomComponent")
public class CustomComponent {
// 1) Still Just returns undefined
@JsProperty(namespace = JsPackage.GLOBAL)
public static native JSFunction getCustomComponent();
// 2) Still crashes compiler with internal error
--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/9b869d0e-960e-48dc-b2d5-87abc587703f%40googlegroups.com.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.
Well I think I have hit a roadblock with the current state of JsInterop. Given the code below
public class Example {
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
private static class State extends BaseState {
public String aStateVar;
}
static public BaseState getInitialState() {
State s = new State();
s.aStateVar = "Initial Value";
return s;
}
protected static final native <S extends BaseState> S getState() /*-{;
return this.state;
}-*/;
static public ReactElement<?> render() {
//getState will not work because the this in the global JSNI function is bound to $Wnd
State ourState = getState();
.
.
}
public native JavaScriptObject makeSpec() /*-{
return {
render : $entry(this.render()),
getInitialState : $entry(this.getInitialState())
};
}-*/;
}
}
--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/ac1fbf90-4b52-4a2e-9224-c4b16a218e17%40googlegroups.com.
Success! With some javascript hacking I have managed to get it working. I can access state and props and set state as a result of an onClick event. I think it might be possible to get react fully working. Below is my somewhat contrived solution
--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/2af4ca30-e14c-477f-aad4-b3d4b2d7a27b%40googlegroups.com.
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
public class AbstractClassicComponent {
protected native void setState(BaseState state);
protected native void setState(BaseState state, ReactCallback callback);
protected native void forceUpdate(ReactCallback callBack);
protected native void replaceState(BaseState nextState, ReactCallback callback);
protected native boolean isMounted();
protected native <P extends BaseProps> P getProps();
protected native <S extends BaseState> S getState();
}
@JsType(namespace = JsPackage.GLOBAL)
public class CustomClassicComponent extends AbstractClassicComponent {
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
public static class Props extends BaseProps {
public String aProp;
}
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
private static class State extends BaseState {
public String aStateVar;
}
public BaseState getInitialState() {
State s = new State();
s.aStateVar = "Initial Value";
return s;
}
public ReactElement<?> render() {
Props ourProps = getProps();
State ourState = getState();
String description = "Click me (state=" + ourState.aStateVar + ", props=" + ourProps.aProp + ")";
MouseEventHandler clickedBtn = (e) -> {
State newState = new State();
newState.aStateVar = "Updated Value";
setState(newState);
};
return React.createElement("button", new HTMLProps().Title("Some title").OnClick(clickedBtn), description);
}
}
public class ReactMain implements EntryPoint {
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
private static class StatelessProps extends BaseProps {
public String aProp;
}
@Override
public void onModuleLoad() {
initJS();
ClassicComponentClass<CustomClassicComponent.Props> customClassicComponent =
React.createClass(GWTReact.makeSpec(new CustomClassicComponent()));
StatelessComponent<StatelessProps> statelessComp =
(props)->{return React.createElement("div", null, "Stateless component works " + props.aProp);};
StatelessProps fProps = new StatelessProps();
fProps.aProp = "Its a func prop";
CustomClassicComponent.Props classicProps= new CustomClassicComponent.Props();
classicProps.aProp = "classic prop";
DOMElement<HTMLProps> div =
React.createElement("div", new HTMLProps().DefaultValue("ss"),
React.createElement("div", null,
React.createElement(statelessComp, fProps)),
React.createElement(customClassicComponent, classicProps),
React.createElement("div", null, "An example")
);
ReactDOM.render(div, Document.get().getElementById("mainCont"));
}
private final native void initJS() /*-{
$wnd.GWTReact = {};
$wnd.GWTReact.makeSpec = function(componentObj) {
var prototype = componentObj.__proto__;
var spec = {
getState: function() {
return this.state;
}
,getProps: function() {
return this.props;
}
};
for (var p in prototype) {
if (prototype.hasOwnProperty(p) && p != 'constructor') {
spec[p] = prototype[p];
}
}
return spec;
}
}-*/;
}The trick is the makeSpec function. I am going to work fleshing out the API so I can build a real test application. I can also improve how you work with state and props.
I am making decent progress refining the API and making it more usable. I have decided to do a direct port