timolins / react-hot-toast

Smoking Hot React Notifications 🔥
https://react-hot-toast.com
MIT License
9.66k stars 319 forks source link

Next.js 13 server components type error #232

Closed transitive-bullshit closed 1 year ago

transitive-bullshit commented 1 year ago

Using a beta of Next.js 13, running next dev with a <Toaster /> in a server component results in:

TypeError: (0 , k.useState) is not a function or its return value is not iterable

I'm guessing this has something to do with react-hot-toast being used in a server component. If I move the `Toaster component into an explicit client component file, it works as expected:

'use client'

import { Toaster } from 'react-hot-toast'

export function Client() {
  return <Toaster position='top-right' />
}

Some notes on env (though I don't think it matters):

pellyadolfo commented 1 year ago

This article explains the issue:

There are numbers of toast components available in react ecosystem. But most popular ones are designed to work on client-side ie — they are suitable for React projects made from create-react-app. As we know NextJs is a react framework that has made Server Side Rendering very easy. To implement toast notification, I have tested some of the popular toast components and found out that most of them are not working properly. Either they need some extra modules to be installed or require changing the next configuration. Some component has styling issues also. So I decided to make my own toast component.

https://medium.com/@ashwaniparker/a-simple-nextjs-compatible-toast-cefdec4f3c11

but it does not work for me either. I was not able to find a Toast component for Next so far

pellyadolfo commented 1 year ago

Finally this worked for me with Next.js

https://stackoverflow.com/a/72815922/2517585

Tomekmularczyk commented 1 year ago

I'm getting this (Nextjs@13.1.6, react-hot-toast@2.4.0) when trying to mount Toaster in layout.tsx:

error - ./node_modules/react-hot-toast/dist/index.mjs
ReactServerComponentsError:

You're importing a component that needs useEffect. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.

EDIT: Seems that it can be fixed by creating a separate file

// Toaster.tsx
"use client" // <--- fix

import { Toaster as HTToaster } from "react-hot-toast";

export const Toaster = HTToaster;

// layout.tsx

import { Toaster } from './Toaster';

export default function RootLayout() {

  return (
    <div>
       <Toaster />
    </div>
  )
}
baba43 commented 1 year ago

Well, turning the whole app to a client component is actually not a fix, it is a very ugly workaround.

Is there smarter solution out there?

timolins commented 1 year ago

This is now fixed with 2.4.1, by including "use client" inside the package. 🙏