Search code examples
javascriptreactjsreact-domcarbon-design-system

ReactDom createPortal() doesn't work but render() does, and only once not if trigger is repeated - why is this?


Newbie to react here.

TLDR: I have a helper function called createNotification which when called inserts a <ToastNotification /> component into a container element using render(). If I use createPortal() nothing is appended. If I use render, the component is only added once despite multiple triggers.

Can anyone help me figure out whats happening please?

Thank you

helpers.js


import { ToastNotification } from "carbon-components-react";
import { render, createPortal } from "react-dom";

export const createNotification = () => {
  const container = document.getElementById("notificationContainer");
  console.log(container); //just to check function is running and has found container
  return render(<ToastNotification />, container); //works but only once, not on multiple triggers
  return createPortal(<ToastNotification />, container); //doesn't render anything in container
};

the function above is called from other components as needed:

login.js

import { createNotification } from "../../helpers";

const Login = () => {
  const validateLogin = async (event) => {
    createNotification();
    // validation logic
    performLogin();
  };

  const performLogin = async () => {
    //axios call here
  };

  // main component content
  return (
    <>
     <!-- validateLogin() called on form submit -->
    </>
  );
};

export default Login;

app.js

//imports

function App() {
  return (
    <div>
      <div className="App"></div>
    </div>
  );
}
export default App;


Thank you


Solution

  • Solved this myself by adding the createPortal() within the render().

    If anyone can provide an explanation, it would be much appreciated.

    export const createNotification = () => {
      const container = document.getElementById("notificationContainer");
      console.log(container);
      return render(createPortal(<ToastNotification />, container), document.createElement("div"));
    };