ReactDOM.render is no longer supported in React 18. Use createRoot instead.

914 views
Skip to first unread message

Sardorbek Omonkulov

unread,
Aug 5, 2023, 3:05:35 PM8/5/23
to Blockly
Hello! 

I am trying to create a custom Blockly field that renders a React component. I am following the given example here. But the example uses an older version of react that supported ReactDom.render. With the new version of react (18+) you get this following warning:

Screenshot 2023-08-05 145053.png

But everything still works. Here is the code and the output:

Screenshot 2023-08-05 150044.png

Screenshot 2023-08-05 145951.png

To get rid of that warning I switched to createRoot. Everything is working as expected and there are no errors. Except there is a UI issue while rendering. Here is the code and the output:


Screenshot 2023-08-05 145528.png

Screenshot 2023-08-05 145444.png



Sardorbek Omonkulov

unread,
Aug 5, 2023, 3:53:07 PM8/5/23
to Blockly

I found one workaround for this but if there is a better way please let me know:

  showEditor_(_e?: Event | undefined): void {
    this.div_ = Blockly.DropDownDiv.getContentDiv();
    this.react_root = ReactDOM.createRoot(this.div_);
    this.react_root.render(this.render());

    var border = this.getSourceBlock()?.getColour();
    let sourceBlock = this.getSourceBlock()?.getColour();
    if (sourceBlock && border) {
      Blockly.DropDownDiv.setColour(sourceBlock, border);
    }

    Blockly.DropDownDiv.showPositionedByField(
      this,
      this.dropdownDispose_.bind(this)
    );

    // Workaround: Sending a resize event renders the dropdown correctly
    setTimeout(() => {
      window.dispatchEvent(new Event("resize"));
    }, 10);

  }

Beka Westberg

unread,
Aug 7, 2023, 12:44:26 PM8/7/23
to blo...@googlegroups.com
Hello :D

Based on the screenshot of the buggy behavior it looks like the size of the react_root / BlocklyReactFieldComponent isn't being properly calculated before the drop down div is positioned. It thinks it has a size of (0, 0), so it's not being centered.

You could try to root cause that issue and figure out why the component isn't being sized properly in time. Or you could try waiting until the next animation frame to position the div (this should ensure all of the sizing information has been calculated.

```
showEditor() {
  // All the stuff to define the react_root.

  // Wait a frame before positioning.
  window.requestAnimationFrame(() => {
    Blockly.DropDownDiv.showPositionedByField(
        this, this.dropdownDispose.bind(this));
  })
}
```

I hope that helps! If you have any further questions please reply =)
--Beka

--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/blockly/b599493c-aa57-4f87-b3b1-3f0b21c0c6e0n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages