fix(settings): typing in the wanderer address and key fields no longer gets undone

useToast handed back a new object on every render. useWandererConnection lists
toast in its load effect, so each keystroke reloaded the saved settings and
reset both fields to them.
This commit is contained in:
Maurice
2026-10-16 11:33:19 +02:00
parent 52ed63715c
commit 33b006014b
2 changed files with 26 additions and 14 deletions
+11 -1
View File
@@ -1,6 +1,7 @@
import { render, screen, act } from '../../../tests/helpers/render';
import userEvent from '@testing-library/user-event';
import { ToastContainer } from './Toast';
import { renderHook } from '@testing-library/react';
import { ToastContainer, useToast } from './Toast';
describe('ToastContainer', () => {
beforeEach(() => {
@@ -92,3 +93,12 @@ describe('ToastContainer', () => {
expect(screen.getByText('Third toast')).toBeTruthy();
});
});
describe('useToast', () => {
it('hands back the same object on every render, so effects that list it do not re-run', () => {
const { result, rerender } = renderHook(() => useToast());
const first = result.current;
rerender();
expect(result.current).toBe(first);
});
});
+15 -13
View File
@@ -1,4 +1,4 @@
import React, { useCallback } from 'react'
import React, { useMemo } from 'react'
import { CheckCircle, XCircle, AlertCircle, Info, X } from 'lucide-react'
import { useToastQueue, type ToastType } from './useToastQueue'
@@ -101,19 +101,21 @@ export function ToastContainer() {
)
}
export const useToast = () => {
const show = useCallback((message: string, type: ToastType, duration?: number) => {
if (window.__addToast) {
window.__addToast(message, type, duration)
// One object for the life of the component: hooks list `toast` in their effect
// dependencies, and a fresh object per render re-ran those effects on every keystroke.
export const useToast = () =>
useMemo(() => {
const show = (message: string, type: ToastType, duration?: number) => {
if (window.__addToast) {
window.__addToast(message, type, duration)
}
}
return {
success: (message: string, duration?: number) => show(message, 'success', duration),
error: (message: string, duration?: number) => show(message, 'error', duration),
warning: (message: string, duration?: number) => show(message, 'warning', duration),
info: (message: string, duration?: number) => show(message, 'info', duration),
}
}, [])
return {
success: (message: string, duration?: number) => show(message, 'success', duration),
error: (message: string, duration?: number) => show(message, 'error', duration),
warning: (message: string, duration?: number) => show(message, 'warning', duration),
info: (message: string, duration?: number) => show(message, 'info', duration),
}
}
export default useToast