From e5494717410ea9b48e73458f4e8bd05b3f75c653 Mon Sep 17 00:00:00 2001 From: minsgy Date: Fri, 31 May 2024 00:08:28 +0900 Subject: [PATCH 1/3] refactor: useSyncExternalStore useStore refactor --- src/core/store.ts | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/core/store.ts b/src/core/store.ts index 506978a..c624bce 100644 --- a/src/core/store.ts +++ b/src/core/store.ts @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react'; +import { useSyncExternalStore } from 'react'; import { DefaultToastOptions, Toast, ToastType } from './types'; const TOAST_LIMIT = 20; @@ -179,16 +179,19 @@ export const defaultTimeouts: { }; export const useStore = (toastOptions: DefaultToastOptions = {}): State => { - const [state, setState] = useState(memoryState); - useEffect(() => { - listeners.push(setState); - return () => { - const index = listeners.indexOf(setState); - if (index > -1) { - listeners.splice(index, 1); - } - }; - }, [state]); + const state = useSyncExternalStore( + (callback) => { + listeners.push(callback); + return () => { + const index = listeners.indexOf(callback); + if (index > -1) { + listeners.splice(index, 1); + } + }; + }, + () => memoryState, + () => memoryState + ); const mergedToasts = state.toasts.map((t) => ({ ...toastOptions, From 7899115719de90681b0a8de20e5e7bfa0f72821a Mon Sep 17 00:00:00 2001 From: Timo Lins Date: Sat, 21 Dec 2024 11:24:46 +0100 Subject: [PATCH 2/3] Bump react peer dependencies Required for `useSyncExternalStore` --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 9866a25..9576dde 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ "goober": "^2.1.10" }, "peerDependencies": { - "react": ">=16", - "react-dom": ">=16" + "react": ">=18", + "react-dom": ">=18" } } From a5f9d1a52149eefa389c06e0333a483c57fed320 Mon Sep 17 00:00:00 2001 From: Timo Lins Date: Mon, 6 Jan 2025 14:50:20 +0100 Subject: [PATCH 3/3] Add test case for toast inside use effect Taken from @jluxenberg PR: #251 Co-Authored-By: Jared Luxenberg --- test/toast.test.tsx | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/test/toast.test.tsx b/test/toast.test.tsx index c528219..a79d689 100644 --- a/test/toast.test.tsx +++ b/test/toast.test.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { render, screen, @@ -319,3 +319,25 @@ test('pause toast', async () => { expect(toastElement).not.toBeInTheDocument(); }); + +test('"toast" can be called from useEffect hook', async () => { + const MyComponent = () => { + const [success, setSuccess] = useState(false); + useEffect(() => { + toast.success('Success toast'); + setSuccess(true); + }, []); + + return success ?
MyComponent finished
: null; + }; + + render( + <> + + + + ); + + await screen.findByText(/MyComponent finished/i); + expect(screen.queryByText(/Success toast/i)).toBeInTheDocument(); +});