Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a React portal be used in a Stateless Functional Component (SFC)?

Tags:

reactjs

I have used ReactDOM.createPortal inside the render method of a stateful component like so:

class MyComponent extends Component {
    ...
    render() {
        return (
            <Wrapper>
                {ReactDOM.createPortal(<FOO />, 'dom-location')}
            </Wrapper>
        )
    }
}

... but can it also be used by a stateless (functional) component?

like image 676
JoeTidee Avatar asked Mar 22 '18 10:03

JoeTidee


People also ask

What are stateless functional components in react?

Stateless functional components in React are pure functions of the passed in props. These components do not rely on state and discard the use of component lifecycle methods. You may, however, still define propTypes and defaultPropts.

How do I create a React component?

There are two ways to create a React component. The first way is to use a JavaScript function. Defining a component in this way creates a stateless functional component. The concept of state in an application will be covered in later challenges.

What is the function of welcome in react?

These components use plain JavaScript functions. function Welcome (props) { return <h1>Hello, {props.name}</h1>; } This function is a valid React component because it accepts a single props object argument with data and returns a React element. We call such components functional because they are literally JavaScript functions.

How to render a stateless component in SSR?

In case of stateless component you can pass element via props and render it via portal. Hope it will helps. If you are trying to use any of the above with SSR (for example NextJS) you may run into difficulty. The following should get you what you need.


3 Answers

Will chime in with an option where you dont want to manually update your index.html and add extra markup, this snippet will dynamically create a div for you, then insert the children.

export const Portal = ({ children, className = 'root-portal', el = 'div' }) => {
  const [container] = React.useState(() => {
    // This will be executed only on the initial render
    // https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
    return document.createElement(el);
  });

  React.useEffect(() => {
    container.classList.add(className)
    document.body.appendChild(container)
    return () => {
      document.body.removeChild(container)
    }
  }, [])

  return ReactDOM.createPortal(children, container)
}

like image 96
Samuel Avatar answered Oct 18 '22 08:10

Samuel


It can be done like this for a fixed component:

const MyComponent = () => ReactDOM.createPortal(<FOO/>, 'dom-location')

or, to make the function more flexible, by passing a component prop:

const MyComponent = ({ component }) => ReactDOM.createPortal(component, 'dom-location')
like image 23
JoeTidee Avatar answered Oct 18 '22 07:10

JoeTidee


can it also be used by a stateless (functional) component ?

yes.

const Modal = (props) => {
      const modalRoot = document.getElementById('myEle');

      return ReactDOM.createPortal(props.children, modalRoot,);
    }

Inside render :

render() {
    const modal = this.state.showModal ? (
      <Modal>
        <Hello/>
        </Modal>
    ) : null;

    return (
      <div>
      <div id="myEle">
        </div>
      </div>
    );
  }

Working codesandbox#demo

like image 21
RIYAJ KHAN Avatar answered Oct 18 '22 08:10

RIYAJ KHAN