-
Notifications
You must be signed in to change notification settings - Fork 842
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[EuiBottomBar] document is not defined when using server rendering #5656
Comments
Two ways to solve; I started by modifying the existing EuiPortal class component to create the @thompsongl @constancecchen I'll open a PR with whichever approach you like better Class componentexport class EuiPortal extends Component<EuiPortalProps, EuiPortalState> {
state: EuiPortalState = {
portalNode: undefined,
};
componentDidMount() {
const { insert } = this.props;
const portalNode = document.createElement('div');
this.setState({ portalNode });
if (insert == null) {
// no insertion defined, append to body
document.body.appendChild(portalNode);
} else {
// inserting before or after an element
const { sibling, position } = insert;
sibling.insertAdjacentElement(insertPositions[position], portalNode);
}
}
componentWillUnmount() {
const { portalNode } = this.state;
if (portalNode && portalNode.parentNode) {
portalNode.parentNode.removeChild(portalNode);
}
this.updatePortalRef(null);
}
updatePortalRef(ref: HTMLDivElement | null) {
if (this.props.portalRef) {
this.props.portalRef(ref);
}
}
render() {
const { portalNode } = this.state;
return portalNode == null
? null
: createPortal(this.props.children, portalNode);
}
} Function componentexport const EuiPortal: React.FC<EuiPortalProps> = ({
insert,
portalRef,
children,
}) => {
const [portalNode, setPortalNode] = useState<HTMLDivElement>();
// mount
useEffect(() => {
const portalNode = document.createElement('div');
setPortalNode(portalNode);
if (insert == null) {
// no insertion defined, append to body
document.body.appendChild(portalNode);
} else {
// inserting before or after an element
const { sibling, position } = insert;
sibling.insertAdjacentElement(insertPositions[position], portalNode);
}
portalRef?.(portalNode);
}, []);
// unmount
useEffect(() => {
return () => {
if (portalNode && portalNode.parentNode) {
portalNode.parentNode.removeChild(portalNode);
}
portalRef?.(null);
};
}, [portalRef, portalNode]);
return portalNode == null ? null : createPortal(children, portalNode);
}; |
Function component 🙌 |
++ to the function component! Just curious, does mount and unmount need to be 2 separate useEffects? Is there a specific reason we can't return the unmount callback in the first useEffect? useEffect(() => {
// mount
const portalNode = document.createElement('div');
setPortalNode(portalNode);
if (insert == null) {
// no insertion defined, append to body
document.body.appendChild(portalNode);
} else {
// inserting before or after an element
const { sibling, position } = insert;
sibling.insertAdjacentElement(insertPositions[position], portalNode);
}
portalRef?.(portalNode);
// unmount
return () => {
if (portalNode && portalNode.parentNode) {
portalNode.parentNode.removeChild(portalNode);
}
portalRef?.(null);
};
}, []); |
@chandlerprall did you ever get around to fixing this? |
Whoops, did not! I'll add it back to my list for this week. |
When attempting to use
EuiBottomBar
in a Remix app, the following error occurs when rendering on the server:The error message looks similar to #4807.
The text was updated successfully, but these errors were encountered: