简体   繁体   中英

React Component getting added in Vaadin 7 only on button click

I have a vaadin7 application to which I am trying to integrate a sample react application. It is working properly when I implement the React component creation inside a button click. But it is not working if I put the code outside the button click. It shows error "Uncaught TypeError: Cannot read property 'appendChild' of null at Module.11 (index.js:9) at u (bootstrap:84) at t (bootstrap:45) at Array.r [as push] (bootstrap:32) at main.90a85973.chunk.js:1" while inspecting.

In vaadin application, i am creating div named "root" and in the index.js of sample react application, I am trying to get the root div created from vaadin and appending "react-root" to "root" div so as to fit the react application in my vaadin layout.

Please find below code for vaadin ui

CustomLayout layout = null;
        try {
            String dynamicHtml = "<div id=\"root\"></div>";
            layout = new CustomLayout(new ByteArrayInputStream(dynamicHtml.getBytes()));
            System.out.println("JS Layout");
        } catch (IOException e) {
            System.out.println("could not create custom layaout"+ e);
        }
        uimainLayout.addComponent(layout);
        

//If the below 4 lines of code are added inside the button click, the reactcomponent is rendered inside the layout properly on clicking the button . Otherwise it is showing the "Uncaught TypeError: Cannot read property 'appendChild' of null"

        VerticalLayout jsmainLayout = new VerticalLayout();
        ReactComponent reactComponent=new ReactComponent();
        jsmainLayout.addComponent(reactComponent);
        uimainLayout.addComponent(jsmainLayout);

        getMainLayout().addComponent(uimainLayout);
        setCompositionRoot(getMainLayout());

My Reactcomponent

@JavaScript({"<ip:port>/static/js/2.1f3e22a9.chunk.js","<ip:port>/static/js/3.583f7bad.chunk.js","<ip:port>/static/js/runtime-main.23689a58.js","<ip:port>/static/js/main.90a85973.chunk.js","ReactComponentConnector.js"})
@StyleSheet("<ip:port>/static/css/main.a617e044.chunk.css")
public class ReactComponent extends AbstractJavaScriptComponent {
    public ReactComponent() {
         System.out.println("Inside ReactComponent");
        
    }
    @Override
    protected ReactComponentState getState() {
        return (ReactComponentState) super.getState();
    }
}

ReactComponentState

public class ReactComponentState extends JavaScriptComponentState {
    private static final long serialVersionUID = -3283446856435450054L;
}

ReactComponentConnector.js

window.com_p1_p2_ReactComponent = function () {

}

Index.js of my sample react application

const rootEl = document.createElement('div')
rootEl.setAttribute('id', 'react-root');
//error points to the below line
const parentEl =document.getElementById('root');
parentEl.appendChild(rootEl)

ReactDOM.render(
    <App />
  ,
  rootEl
);
reportWebVitals();

It's not clear exactly what it is that triggers running the code listed for index.js , but it would seem like it's run before the contents of the custom layout has been initialized. In that way, no element with the id root exists and this would cause the reported error.

I assume creation happens through new ReactComponent(this.getElement()) from inside the JS connector initializer. If this is the case, then they reason for the problem is that both the actions (set custom layout content and initialize the JS connector) are sent to the browser in the same batch, but the connector is initialized in an earlier phase. If the JS component is sent in a batch triggered though a click listener, then this won't be a problem.

To solve this, you could use a direct element reference instead of relying on getElementById in combination with an id defined in the content of a custom layout. The easiest way would be if you'd restructure to use the this.getElement() instance that you're now passing to the ReactComponent constructor.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM