GWTReact / gwt-react

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

Extending native React components #11

Closed morten-holm closed 7 years ago

morten-holm commented 7 years ago

We are trying to use the Office Fabric UI components that are a set of React components from gwt-react. We use this version of Fabric: https://unpkg.com/office-ui-fabric-react@4.38.0/dist/office-ui-fabric-react.js

What has been working so far is something like this:

@JsType(isNative = true, namespace = JsPackage.GLOBAL)
public class Fabric {
    public static ComponentConstructorFn<BaseProps> PrimaryButton;
    public static ComponentConstructorFn<BaseProps> DefaultButton;
    public static ComponentConstructorFn<BaseProps> DetailsList;
}

and

React.createElement(DetailsList.class, new BaseProps());

But what we really would like to do is something like this:

@JsType(isNative = true, namespace = "Fabric")
public class DetailsList extends Component<BaseProps, JsPlainObj> {

    public DetailsList(BaseProps props) {
        super(props);
    }

    protected native ReactElement<?, ?> render();
}

We want this to be able to add methods that are able to invoke setState().

Can it be done and is this even the 'correct' approach?

pstockley commented 7 years ago

In the React world, you would usually use composition instead of inheritance. Take a look at https://facebook.github.io/react/docs/higher-order-components.html

morten-holm commented 7 years ago

Exactly what i needed.

I got it working like this:

@JsType
public class FabricTable extends Component<BaseProps, JsPlainObj> implements ComponentWillMount {
    @JsConstructor
    public FabricTable(BaseProps props) {
        super(props);
    }

    @Override
    public void componentWillMount() {
        setItems(this.props.getObj("items"));
    }

    @Override
    protected ReactElement<?, ?> render() {
        return React.createElement(Fabric.DetailsList, $(new BaseProps(), "items", this.state.getObj("items")));
    }

    public void setItems(Array<Item> newItems) {
        setState($(new BaseProps(), "items", newItems));
    }
}

Thank you.