radix-ui / primitives

Radix Primitives is an open-source UI component library for building high-quality, accessible design systems and web apps. Maintained by @workos.
https://radix-ui.com/primitives
MIT License
15.44k stars 775 forks source link

_callbackRef$current.call is not a function when calling toast with a button in a different component. #1802

Closed Mbensler closed 1 year ago

Mbensler commented 1 year ago

Bug report

Current Behavior

I am trying to call the Toast primitive with a button in another component. The toast shows up but after 5-15 seconds an error pops up saying: TypeError: _callbackRef$current.call is not a function

Additional context

My code looks like this, nothing special:

// TOAST COMPONENT

import * as React from 'react';
import * as Toast from '@radix-ui/react-toast';
import { styled, keyframes } from '@stitches/react';
import { violet, blackA, mauve, slate, green } from '@radix-ui/colors';

const ToastDemo = (open, setOpen) => {
  const eventDateRef = React.useRef(new Date());

 // const [open, setOpen] = React.useState(false);
 // const eventDateRef = React.useRef(new Date());
 // const timerRef = React.useRef(0);

 // React.useEffect(() => {
  //  return () => clearTimeout(timerRef.current);
 // }, []);

  return (
    <Toast.Provider swipeDirection="right">
      {/* -------------- IT WORKS WITH THIS BUTTON --------------  */}
      {/* <Button
        onClick={() => {
          setOpen(false);
          window.clearTimeout(timerRef.current);
          timerRef.current = window.setTimeout(() => {
            setOpen(true);
          }, 100);
        }}
      >
        Add to calendar
      </Button> */}
      <ToastRoot duration={5000} open={open} onOpenChange={setOpen}>
        <ToastTitle>Scheduled: Catch up</ToastTitle>
        <ToastDescription asChild>
          <time dateTime={eventDateRef.current.toISOString()}>
            {prettyDate(eventDateRef.current)}
          </time>
        </ToastDescription>
        <ToastAction asChild altText="Goto schedule to undo">
          <Button size="small" variant="green">
            Undo
          </Button>
        </ToastAction>
      </ToastRoot>
      <ToastViewport />
    </Toast.Provider>
  );
};

MY TEST COMPONENT WHERE I WANT TO CALL THE BUTTON THAT SHOWS THE TOAST

import * as React from 'react';

const Test = () => {
  const [open, setOpen] = React.useState(false);

  const timerRef = React.useRef(0);

  React.useEffect(() => {
      return () => clearTimeout(timerRef.current);
  }, []);

  return (
      <Button
        onClick={() => {
          setOpen(false);
          window.clearTimeout(timerRef.current);
          timerRef.current = window.setTimeout(() => {
            setOpen(true);
          }, 100);
        }}
      >
        Add to calendar
      </Button>
      {open && <ToastDemo open={open} setOpen={setOpen} />}
  );
};

This also shows the toast just fine, but after 5-15 seconds i get this error: TypeError: _callbackRef$current.call is not a function

The only thing I am doing is moving the state stuff to the other component where the button is calling the Toast, but I cant get it working. I'm not sure if it's a bug?

Your environment

Software Name(s) Version
Radix Package(s) @radix-ui/react-toast 1.1.2
React n/a 18.2.0
Browser All Newest
Assistive tech
Node n/a 18.12.1
npm/yarn yarn 1.22.19
andy-hook commented 1 year ago

const ToastDemo = (open, setOpen) => {

You should destructure:

const ToastDemo = ({open, setOpen}) => {

Mbensler commented 1 year ago

Wow, I'm bad. I was sure I had already tried that. It works. Thanks :)