22
33import React, { useCallback, useReducer, useLayoutEffect } from 'react'
44import { createStore } from 'redux'
5- import { renderHook, act } from '@testing-library/react-hooks'
65import * as rtl from '@testing-library/react'
76import {
87 Provider as ProviderMock,
@@ -15,7 +14,6 @@ import { useReduxContext } from '../../src/hooks/useReduxContext'
1514import type { FunctionComponent, DispatchWithoutAction, ReactNode } from 'react'
1615import type { Store, AnyAction } from 'redux'
1716import type {
18- ProviderProps,
1917 TypedUseSelectorHook,
2018 ReactReduxContextValue,
2119 Subscription,
@@ -44,41 +42,55 @@ describe('React', () => {
4442 afterEach(() => rtl.cleanup())
4543
4644 describe('core subscription behavior', () => {
47- type PropsTypeDelStore = Omit<ProviderProps, 'store'>
48-
4945 it('selects the state on initial render', () => {
50- const { result } = renderHook(
51- () => useNormalSelector((s) => s.count),
52- {
53- wrapper: (props: PropsTypeDelStore) => (
54- <ProviderMock {...props} store={normalStore} />
55- ),
56- }
46+ let result: number | undefined
47+ const Comp = () => {
48+ const count = useNormalSelector((state) => state.count)
49+
50+ useLayoutEffect(() => {
51+ result = count
52+ }, [])
53+ return <div>{count}</div>
54+ }
55+
56+ rtl.render(
57+ <ProviderMock store={normalStore}>
58+ <Comp />
59+ </ProviderMock>
5760 )
5861
59- expect(result.current ).toEqual(0)
62+ expect(result).toEqual(0)
6063 })
6164
6265 it('selects the state and renders the component when the store updates', () => {
6366 type MockParams = [NormalStateType]
6467 const selector: jest.Mock<number, MockParams> = jest.fn(
6568 (s) => s.count
6669 )
70+ let result: number | undefined
71+ const Comp = () => {
72+ const count = useNormalSelector(selector)
6773
68- const { result } = renderHook (() => useNormalSelector(selector), {
69- wrapper: (props: PropsTypeDelStore) => (
70- <ProviderMock {...props} store={normalStore} />
71- ),
72- })
74+ useLayoutEffect (() => {
75+ result = count
76+ })
77+ return <div>{count}</div>
78+ }
7379
74- expect(result.current).toEqual(0)
80+ rtl.render(
81+ <ProviderMock store={normalStore}>
82+ <Comp />
83+ </ProviderMock>
84+ )
85+
86+ expect(result).toEqual(0)
7587 expect(selector).toHaveBeenCalledTimes(1)
7688
77- act(() => {
89+ rtl. act(() => {
7890 normalStore.dispatch({ type: '' })
7991 })
8092
81- expect(result.current ).toEqual(1)
93+ expect(result).toEqual(1)
8294 expect(selector).toHaveBeenCalledTimes(2)
8395 })
8496 })
@@ -102,7 +114,7 @@ describe('React', () => {
102114
103115 expect(renderedItems).toEqual([1])
104116
105- act(() => {
117+ rtl. act(() => {
106118 store.dispatch({ type: '' })
107119 })
108120
@@ -132,7 +144,7 @@ describe('React', () => {
132144 // @ts-ignore ts(2454)
133145 expect(rootSubscription.getListeners().get().length).toBe(1)
134146
135- act(() => {
147+ rtl. act(() => {
136148 normalStore.dispatch({ type: '' })
137149 })
138150
@@ -163,7 +175,7 @@ describe('React', () => {
163175 // @ts-ignore ts(2454)
164176 expect(rootSubscription.getListeners().get().length).toBe(2)
165177
166- act(() => {
178+ rtl. act(() => {
167179 normalStore.dispatch({ type: '' })
168180 })
169181
@@ -210,8 +222,7 @@ describe('React', () => {
210222 // With `useSyncExternalStore`, we get three renders of `<Comp>`:
211223 // 1) Initial render, count is 0
212224 // 2) Render due to dispatch, still sync in the initial render's commit phase
213- // TODO 3) ??
214- expect(renderedItems).toEqual([0, 1, 1])
225+ expect(renderedItems).toEqual([0, 1])
215226 })
216227 })
217228
@@ -274,7 +285,7 @@ describe('React', () => {
274285
275286 expect(renderedItems.length).toBe(1)
276287
277- act(() => {
288+ rtl. act(() => {
278289 store.dispatch({ type: '' })
279290 })
280291
@@ -309,7 +320,7 @@ describe('React', () => {
309320
310321 expect(renderedItems.length).toBe(1)
311322
312- act(() => {
323+ rtl. act(() => {
313324 store.dispatch({ type: '' })
314325 })
315326
@@ -346,7 +357,7 @@ describe('React', () => {
346357 expect(numCalls).toBe(1)
347358 expect(renderedItems.length).toEqual(1)
348359
349- act(() => {
360+ rtl. act(() => {
350361 store.dispatch({ type: '' })
351362 })
352363
@@ -398,9 +409,7 @@ describe('React', () => {
398409
399410 // Selector first called on Comp mount, and then re-invoked after mount due to useLayoutEffect dispatching event
400411 expect(numCalls).toBe(2)
401- // TODO As with "notice store updates" above, we're now getting _3_ renders here
402- // expect(renderedItems.length).toEqual(2)
403- expect(renderedItems.length).toEqual(3)
412+ expect(renderedItems.length).toEqual(2)
404413 })
405414 })
406415
@@ -504,7 +513,7 @@ describe('React', () => {
504513 // TODO We can no longer catch errors in selectors after dispatch ourselves, as `uSES` swallows them.
505514 // The test selector will happen to re-throw while rendering and we do see that.
506515 expect(() => {
507- act(() => {
516+ rtl. act(() => {
508517 store.dispatch({ type: '' })
509518 })
510519 }).toThrow(/Panic!/)
@@ -539,7 +548,7 @@ describe('React', () => {
539548 )
540549
541550 expect(() => {
542- act(() => {
551+ rtl. act(() => {
543552 normalStore.dispatch({ type: '' })
544553 })
545554 }).toThrowError()
@@ -614,7 +623,7 @@ describe('React', () => {
614623
615624 expect(renderedItems.length).toBe(1)
616625
617- act(() => {
626+ rtl. act(() => {
618627 normalStore.dispatch({ type: '' })
619628 })
620629
0 commit comments