首页 > 解决方案 > 仅在单击按钮时才在 Vaadin 7 中添加 React 组件

问题描述

我有一个 vaadin7 应用程序,我正在尝试将一个示例反应应用程序集成到该应用程序中。当我在按钮单击中实现 React 组件创建时,它工作正常。但是,如果我将代码放在按钮单击之外,它就不起作用。它显示错误“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) 在 main.90a85973.chunk.js:1" 检查时。

在 vaadin 应用程序中,我正在创建名为“root”的 div,并且在示例 react 应用程序的 index.js 中,我试图获取从 vaadin 创建的根 div 并将“react-root”附加到“root”div 以适应我的 vaadin 布局中的反应应用程序。

请在下面找到 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);
        

//如果在按钮点击中添加以下4行代码,则在点击按钮时reactcomponent会正确呈现在布局中。否则它会显示“未捕获的类型错误:无法读取 null 的属性 'appendChild'”

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

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

我的反应组件

@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();
    }
}

反应组件状态

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

ReactComponentConnector.js

window.com_p1_p2_ReactComponent = function () {

}

我的示例反应应用程序的 Index.js

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();

标签: reactjsintegrationvaadin7

解决方案


目前尚不清楚究竟是什么触发了运行列出的代码index.js,但它似乎是在自定义布局的内容初始化之前运行的。这样,不root存在具有 id 的元素,这将导致报告的错误。

我假设创建是通过new ReactComponent(this.getElement())JS 连接器初始化程序内部发生的。如果是这种情况,那么问题的原因是两个操作(设置自定义布局内容和初始化 JS 连接器)在同一批次中发送到浏览器,但连接器在较早的阶段被初始化。如果 JS 组件是通过点击监听器触发的批量发送的,那么这不会是一个问题。

为了解决这个问题,您可以使用直接元素引用,而不是依赖getElementById与自定义布局内容中定义的 id 组合。最简单的方法是,如果您要重组以使用this.getElement()您现在传递给 ReactComponent 构造函数的实例。


推荐阅读