import React, { useEffect } from 'react' import { act, screen } from '@testing-library/react' import { renderToString } from 'react-dom/server' import { describe, expect, it, vi } from 'vitest' import { create } from 'zustand' interface BearStoreState { bears: number } interface BearStoreAction { increasePopulation: () => void } const initialState = { bears: 0 } const useBearStore = create((set) => ({ ...initialState, increasePopulation: () => set(({ bears }) => ({ bears: bears + 1 })), })) function Counter() { const bears = useBearStore(({ bears }) => bears) const increasePopulation = useBearStore( ({ increasePopulation }) => increasePopulation, ) useEffect(() => { increasePopulation() }, [increasePopulation]) return
bears: {bears}
} describe.skipIf(!React.version.startsWith('18'))( 'ssr behavior with react 18', () => { it('should handle different states between server and client correctly', async () => { const { hydrateRoot } = await vi.importActual( 'react-dom/client', ) const view = renderToString( Loading...}> , ) const container = document.createElement('div') document.body.appendChild(container) container.innerHTML = view expect(container).toHaveTextContent(/bears: 0/) await act(async () => { hydrateRoot( container, Loading...}> , ) }) const bearCountText = await screen.findByText('bears: 1') expect(bearCountText).toBeInTheDocument() document.body.removeChild(container) }) it('should not have hydration errors', async () => { const useStore = create(() => ({ bears: 0, })) const { hydrateRoot } = await vi.importActual( 'react-dom/client', ) const Component = () => { const bears = useStore((state) => state.bears) return
bears: {bears}
} const view = renderToString( Loading...}> , ) const container = document.createElement('div') document.body.appendChild(container) container.innerHTML = view expect(container).toHaveTextContent(/bears: 0/) const consoleMock = vi.spyOn(console, 'error') const hydratePromise = act(async () => { hydrateRoot( container, Loading...}> , ) }) // set state during hydration useStore.setState({ bears: 1 }) await hydratePromise expect(consoleMock).toHaveBeenCalledTimes(0) const bearCountText = await screen.findByText('bears: 1') expect(bearCountText).toBeInTheDocument() document.body.removeChild(container) }) }, )