Using a React Component Within a Dialog?

Hello,
I am trying to render a dialog within React and I am unable to render a React component within the dialog itself. It looks like everything needs to be a string. Is there any way to render a react component within a root for a dialog?

Here is what I have that just shows “object object”

import React, { Component }  from 'react'
import '@vaadin/vaadin-dialog' // vaadin-dialog

function DialogScreen(props){
	return(
	<div>
		<label>Email
		<input type="email" value={props.email} />
	</label>
	<label>Roles
		<input type="text" value={JSON.stringify(props.roles)} />
		</label>
		<button>Save</button>
		</div>
	)
}

export default class Dialog extends Component{
	constructor(props){
		super(props)
		this.dialogRenderer = this.dialogRenderer.bind(this)
	}

	dialogRenderer(root, dialog){
		root.append(<DialogScreen email={this.props.currentUser ? this.props.currentUser.email : null} roles={this.props.currentUser ? this.props.currentUser.roles : null} />)
	}

	componentDidMount(){
		this.dialog.renderer = this.dialogRenderer
		this.dialog.addEventListener('opened-changed', e=> e.detail.value ? null : this.props.handleClose())
	}

	render(){
		const label = this.props.currentUser ? "Modify User" : "Add User"
		return(
				<vaadin-dialog ref={r=>this.dialog = r} aria-label={label} opened={this.props.isOpened}></vaadin-dialog>
		)
	}
}

Thank you,

Hello,
I am trying to render a dialog within React and I am unable to render a React component within the dialog itself. It looks like everything needs to be a string. Is there any way to render a react component within a root for a dialog?

Here is what I have that just shows “object object”

import React, { Component }  from 'react'
import '@vaadin/vaadin-dialog' // vaadin-dialog

function DialogScreen(props){
	return(
	<div>
		<label>Email
		<input type="email" value={props.email} />
	</label>
	<label>Roles
		<input type="text" value={JSON.stringify(props.roles)} />
		</label>
		<button>Save</button>
		</div>
	)
}

export default class Dialog extends Component{
	constructor(props){
		super(props)
		this.dialogRenderer = this.dialogRenderer.bind(this)
	}

	dialogRenderer(root, dialog){
		root.append(<DialogScreen email={this.props.currentUser ? this.props.currentUser.email : null} roles={this.props.currentUser ? this.props.currentUser.roles : null} />)
	}

	componentDidMount(){
		this.dialog.renderer = this.dialogRenderer
		this.dialog.addEventListener('opened-changed', e=> e.detail.value ? null : this.props.handleClose())
	}

	render(){
		const label = this.props.currentUser ? "Modify User" : "Add User"
		return(
				<vaadin-dialog ref={r=>this.dialog = r} aria-label={label} opened={this.props.isOpened}></vaadin-dialog>
		)
	}
}

Thank you,

Hello, root in a renderer is a DOM node, not managed by React. So you should render to it using corresponding API:

ReactDOM.render(<DialogScreen email={this.props.currentUser ? this.props.currentUser.email : null} />, root)

If you wish to retain context, you should consider using Portals. Example: https://github.com/tomivirkki/react-vaadin-components/blob/master/src/Rendered.js

Perfect, thank you both, I didn’t know about that React version of the Vaadin components.

Hello Serhii,
My problem is that the renderer function is not actually called, so I am not able to access the root. Any idea on how to get around this?

I didn’t know about that React version of the Vaadin components.

Note that this isn’t an official Vaadin product, but more like my personal hobby project.

@Tomi they work great, I’ve started using them and the syntax is a little different, than the Vaadin API, but your example file is pretty clear.