|
1 | 1 | /*eslint-disable react/prop-types*/
|
2 | 2 |
|
3 |
| -import React, { useCallback, useReducer } from 'react' |
| 3 | +import React, { useCallback, useReducer, useLayoutEffect } from 'react' |
4 | 4 | import { createStore } from 'redux'
|
5 | 5 | import { renderHook, act } from '@testing-library/react-hooks'
|
6 | 6 | import * as rtl from '@testing-library/react'
|
@@ -156,6 +156,42 @@ describe('React', () => {
|
156 | 156 | })
|
157 | 157 | })
|
158 | 158 |
|
| 159 | + it('works properly with memoized selector with dispatch in Child useLayoutEffect', () => { |
| 160 | + store = createStore(c => c + 1, -1) |
| 161 | + |
| 162 | + const Comp = () => { |
| 163 | + const selector = useCallback(c => c, []) |
| 164 | + const count = useSelector(selector) |
| 165 | + renderedItems.push(count) |
| 166 | + return <Child parentCount={count} /> |
| 167 | + } |
| 168 | + |
| 169 | + const Child = ({ parentCount }) => { |
| 170 | + useLayoutEffect(() => { |
| 171 | + if (parentCount === 1) { |
| 172 | + store.dispatch({ type: '' }) |
| 173 | + } |
| 174 | + }, [parentCount]) |
| 175 | + return <div>{parentCount}</div> |
| 176 | + } |
| 177 | + |
| 178 | + rtl.render( |
| 179 | + <ProviderMock store={store}> |
| 180 | + <Comp /> |
| 181 | + </ProviderMock> |
| 182 | + ) |
| 183 | + |
| 184 | + // The first render doesn't trigger dispatch |
| 185 | + expect(renderedItems).toEqual([0]) |
| 186 | + |
| 187 | + // This dispatch triggers another dispatch in useLayoutEffect |
| 188 | + rtl.act(() => { |
| 189 | + store.dispatch({ type: '' }) |
| 190 | + }) |
| 191 | + |
| 192 | + expect(renderedItems).toEqual([0, 1, 2]) |
| 193 | + }) |
| 194 | + |
159 | 195 | describe('performance optimizations and bail-outs', () => {
|
160 | 196 | it('defaults to ref-equality to prevent unnecessary updates', () => {
|
161 | 197 | const state = {}
|
|
0 commit comments