File tree 4 files changed +73
-6
lines changed
4 files changed +73
-6
lines changed Original file line number Diff line number Diff line change
1
+ import type { ReactNode } from 'react' ;
2
+ import { hydrateRoot } from 'react-dom/client' ;
3
+ import { renderToString } from 'react-dom/server' ;
4
+ import { act } from 'react-dom/test-utils' ;
5
+
6
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
+ export const renderHookServer = < Hook extends ( ) => any > (
8
+ useHook : Hook ,
9
+ {
10
+ wrapper : Wrapper ,
11
+ } : {
12
+ wrapper ?: ( { children } : { children : ReactNode } ) => JSX . Element ;
13
+ } = { } ,
14
+ ) : {
15
+ result : { current : ReturnType < Hook > | undefined } ;
16
+ hydrate : ( ) => void ;
17
+ } => {
18
+ // Store hook return values
19
+ const results : ReturnType < Hook > [ ] = [ ] ;
20
+
21
+ const result = {
22
+ get current ( ) {
23
+ return results . slice ( - 1 ) [ 0 ] ;
24
+ } ,
25
+ } ;
26
+
27
+ const setValue = ( value : ReturnType < Hook > ) => {
28
+ results . push ( value ) ;
29
+ } ;
30
+
31
+ const Component = ( { useHook } : { useHook : Hook } ) => {
32
+ setValue ( useHook ( ) ) ;
33
+ return null ;
34
+ } ;
35
+
36
+ const component = Wrapper ? (
37
+ < Wrapper >
38
+ < Component useHook = { useHook } />
39
+ </ Wrapper >
40
+ ) : (
41
+ < Component useHook = { useHook } />
42
+ ) ;
43
+
44
+ // Render hook on server
45
+ const serverOutput = renderToString ( component ) ;
46
+
47
+ // Render hook on client
48
+ const hydrate = ( ) => {
49
+ const root = document . createElement ( 'div' ) ;
50
+ root . innerHTML = serverOutput ;
51
+ act ( ( ) => {
52
+ hydrateRoot ( root , component ) ;
53
+ } ) ;
54
+ } ;
55
+
56
+ return {
57
+ result,
58
+ hydrate : hydrate ,
59
+ } ;
60
+ } ;
Original file line number Diff line number Diff line change 3
3
"declaration" : true ,
4
4
"esModuleInterop" : true ,
5
5
"isolatedModules" : true ,
6
+ "jsx" : " react-jsx" ,
6
7
"module" : " nodenext" ,
7
8
"noEmit" : true ,
8
9
"noUncheckedIndexedAccess" : true ,
Original file line number Diff line number Diff line change 1
1
import { defineConfig } from 'vitest/config' ;
2
2
3
3
export default defineConfig ( {
4
- resolve : {
5
- alias : {
6
- '@testing-library/react' : '@testing-library/react/server' ,
7
- } ,
8
- } ,
9
4
test : {
10
5
environment : 'node' ,
11
- setupFiles : 'vitest.setup.ts' ,
6
+ setupFiles : [ 'vitest.setup.ts' , 'vitest.setup.node.ts' ] ,
12
7
watch : false ,
13
8
} ,
14
9
} ) ;
Original file line number Diff line number Diff line change
1
+ import { vi } from 'vitest' ;
2
+ import { renderHookServer } from './test-utils.js' ;
3
+
4
+ vi . mock ( '@testing-library/react' , async ( ) => {
5
+ const actualTestingLibraryReact = await vi . importActual ( '@testing-library/react' ) ;
6
+
7
+ return {
8
+ ...actualTestingLibraryReact ,
9
+ renderHook : renderHookServer ,
10
+ } ;
11
+ } ) ;
You can’t perform that action at this time.
0 commit comments