cf.completefrontend

Write the codeHard

Build a Toast that renders into document.body and dismisses itself

Toast takes message (a string, or null when there's nothing to show), onDismiss, and duration in milliseconds (3000 when it isn't given). Wherever it's rendered, even inside a carousel with overflow: hidden and a transform, its DOM goes into document.body through a portal.

It always renders a <div role="status">, empty while message is null, because screen readers only announce changes to a live region that's already on the page. While there's a message, the region holds <p>{message}</p> and a Dismiss button that calls onDismiss.

duration ms after a message appears, call onDismiss once. A new message starts the clock again. A parent that re-renders and passes a new onDismiss function, as the inline arrow below does on every render, must not restart it. Leave no timer waiting once the message is gone or the Toast unmounts.

function Shelf() {
  const [message, setMessage] = useState(null);
  return (
    <div className="carousel">
      <button onClick={() => setMessage("Added Sencha to your cart")}>Add Sencha</button>
      <Toast message={message} onDismiss={() => setMessage(null)} />
    </div>
  );
}
Write this (Toast.jsx)
import { useEffect } from "react";
import { createPortal } from "react-dom";
 
export default function Toast({ message, onDismiss, duration = 3000 }) {
  // Render into document.body, and call onDismiss after duration ms.
  if (!message) return null;
  return (
    <div role="status">
      <p>{message}</p>
      <button onClick={onDismiss}>Dismiss</button>
    </div>
  );
}
The checks your code must pass
  • renders into document.body, outside its parent
  • keeps an empty status region on the page while there's no message
  • Dismiss calls onDismiss
  • calls onDismiss once, duration ms after the message appears
  • waits 3000 ms when there's no duration
  • a parent re-render with a new onDismiss doesn't restart the clock
  • a new message starts the clock again
  • leaves no timer waiting once the message is gone or the Toast unmounts

Try it in the editor

The answer

Write it yourself first. Then compare it with a reference solution and the checks it passes.

Checking your sign-in…