Skip to content
This repository has been archived by the owner on Dec 16, 2021. It is now read-only.

Implement createPortal API #452

Closed
evan-scott-zocdoc opened this issue Dec 19, 2017 · 21 comments
Closed

Implement createPortal API #452

evan-scott-zocdoc opened this issue Dec 19, 2017 · 21 comments
Assignees
Milestone

Comments

@evan-scott-zocdoc
Copy link

https://reactjs.org/docs/portals.html

@developit
Copy link
Member

Likely doable via preact-portal

@jeberly
Copy link

jeberly commented Jan 16, 2018

This is causing problems when trying to leverage https://ant.design/

@jachicao
Copy link

jachicao commented Feb 5, 2018

Also material-ui

@developit
Copy link
Member

This is #1 on the todo list.

@developit developit added this to the 4.0 milestone Feb 23, 2018
@developit developit self-assigned this Feb 23, 2018
@ducwings
Copy link

ducwings commented Mar 4, 2018

also in 'reactstrap` (beta)

61:13-25 "export 'createPortal' was not found in 'react-dom'
 @ ./node_modules/react-portal/es/Portal.js
 @ ./node_modules/react-portal/es/PortalCompat.js
 @ ./node_modules/react-portal/es/index.js
 @ ./node_modules/reactstrap/dist/reactstrap.es.js```

@sammoore
Copy link

sammoore commented Mar 15, 2018

I took a swing at implementing this (very naively), but no success; render fails with <undefined></undefined> output. I'm going to take a deeper look and also set up a smaller project to reproduce.

If there's anyway to get a stack trace on an undefined tag, that would be helpful, but I assume the only reason that's not happening is because the root of the issue comes from the custom code in preact-compat that I've added.

@marvinhagemeister
Copy link
Member

When you enable the debug tools you have callback where you can make custom assertions on each vnode object. It has a check if the tag is undefined already built-in. That should help :)

@eveningkid
Copy link

eveningkid commented Apr 15, 2018

So actually, quick question: is it only related to preact-compat or preact itself? I'm still thinking about switching to preact as the error shows up because of antd package in my case.

Would the same error show up without using the compatibility layer but preact directly?

@developit
Copy link
Member

@samtheprogram hiya! Mind joining our chat?
https://preact-slack.now.sh

@sammoore
Copy link

Hey @developit, I've joined under the same username as my GitHub account!

@ev-dev
Copy link

ev-dev commented May 6, 2018

Also breaks compatibility with searchkit (elasticsearch component library) with the same error of export createPortal not found in react-dom. I assume all use of the Portal API is not currently available

@Madhu0
Copy link

Madhu0 commented May 22, 2018

I was trying to achieve something similar to createPortal using render method. But i am unable to pass context to the child components. Here is what i am doing..

class BaseModal extends Component {

	constructor(props) {
		super(props);
		this.id = (new Date()).getTime() + '';
		this.element = '';
	}

	componentDidMount() {
		console.log('In mount');
		const { children } = this.props;
		this.element = render(<div id={this.id}>{children}</div>, document.getElementById('modal-div'));
	}

	componentDidUpdate() {
		const el = document.getElementById(this.id);
		el.parentElement.removeChild(el);

		const { children } = this.props;
		this.element = render(<div id={this.id}>{children}</div>, document.getElementById('modal-div'));
	}

	componentWillUnmount() {
		console.log('In unmount');
		const el = document.getElementById(this.id);
		el.parentElement.removeChild(el);
	}

	render() {
		console.log(this.context);
		// const childrenWithPrpos = children.map((child, index) => cloneElement(child, this.props));
		return '';
	}
}
class Test extends Component {
    render(){
        return(<BaseModal>{this.props.children}</BaseModal>)
    }
}

Here context is not passed to children, as it is not rendered as a child.

@Kanaye
Copy link

Kanaye commented May 22, 2018

Hey @Madhu0.
I updated your example code to use a wrapper component to pass the context.
You find it here in the preact repl.

@Madhu0
Copy link

Madhu0 commented May 23, 2018

Hey @Kanaye, this works. Thank you for your time.

If we can provide props and context to the component which will be mounted somewhere outside our actual app, aren't we achieving everything React.createPortal does? am i missing something?

I am trying to understand the portal implementation in react, i've gone through createPortal source code and i wasn't able to understand completely. But the basic idea is, it should work just like any other component inside our app, right?

We can even use render(App, target, previousApp) to find the diff in DOM and update, instead of deleting it and rendering it again.

@developit
Copy link
Member

@Madhu0 around 90% of it, yes. They also redirect event bubbling through portal boundaries, which Preact is unlikely to ever do.

@ar1a
Copy link

ar1a commented May 31, 2018

This is causing an issue with react-md,

./node_modules/react-md/es/Helpers/Portal.js
11:23-35 'react-dom' does not contain an export named 'createPortal'.

@armand1m
Copy link

armand1m commented Jun 5, 2018

is there any thing we can do while this is not implemented?

@mozillo
Copy link

mozillo commented Jun 14, 2018

Same issue with react-select

'react-dom' does not contain an export named 'createPortal'

@developit
Copy link
Member

If anyone wants to PR the implementation, something like this would work:

import { h } from 'preact';
import Portal from 'preact-portal';

export function createPortal(child, container) {
  return <Portal into={container}>{child}</Portal>
}

@developit
Copy link
Member

nevermind, there was a much smaller and simpler way and I've implemented it in #486. If anyone has time to test it out that would be lovely.

marvinhagemeister added a commit that referenced this issue Jul 13, 2018
Implement createPortal(). Fixes #452.
@29rayb
Copy link

29rayb commented Jul 23, 2018

I'm getting the same error about 'createPortal' above.
I know it's not yet released, but I've copied the updates for 'createPortal' from https://github.com/developit/preact-compat/blob/master/src/index.js but am still getting this error:

129:12-33 "export 'createPortal' (imported as 'ReactDOM') was not found in 'react-dom'

What am I missing?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests