|
1 | | -import React, { Component, useState } from 'react'; |
| 1 | +import React, { |
| 2 | + Component, |
| 3 | + useState, |
| 4 | + StrictMode, |
| 5 | + useEffect, |
| 6 | + useRef, |
| 7 | +} from 'react'; |
2 | 8 | import { |
3 | 9 | render, |
4 | 10 | cleanup, |
5 | 11 | fireEvent, |
| 12 | + act, |
6 | 13 | } from '@testing-library/react/pure'; |
7 | 14 | // eslint-disable-next-line import/no-unresolved |
8 | 15 | import { view, store, batch } from '@risingstack/react-easy-state'; |
@@ -111,6 +118,55 @@ describe('edge cases', () => { |
111 | 118 | expect(RawChild.mock.calls.length).toBe(1); |
112 | 119 | }); |
113 | 120 |
|
| 121 | + test('should not perform an update on an unmounted component (Strict Mode)', () => { |
| 122 | + const person = store({ name: 'Bob' }); |
| 123 | + |
| 124 | + function MyComp() { |
| 125 | + const [showChild, setChild] = useState(true); |
| 126 | + return ( |
| 127 | + <StrictMode> |
| 128 | + <div> |
| 129 | + <button |
| 130 | + onClick={() => setChild(value => !value)} |
| 131 | + type="button" |
| 132 | + > |
| 133 | + Toggle Child |
| 134 | + </button> |
| 135 | + {showChild && <Child />} |
| 136 | + </div> |
| 137 | + </StrictMode> |
| 138 | + ); |
| 139 | + } |
| 140 | + |
| 141 | + const RawChild = jest.fn().mockImplementation(function Child() { |
| 142 | + const isMouted = useRef(false); |
| 143 | + useEffect(() => { |
| 144 | + isMouted.current = true; |
| 145 | + }, []); |
| 146 | + return <p>{person.name}</p>; |
| 147 | + }); |
| 148 | + const Child = view(RawChild); |
| 149 | + |
| 150 | + jest.spyOn(global.console, 'error'); |
| 151 | + |
| 152 | + const { container } = render(<MyComp />); |
| 153 | + |
| 154 | + // Hide the Child component. |
| 155 | + act(() => { |
| 156 | + fireEvent.click(container.querySelector('button')); |
| 157 | + }); |
| 158 | + // Show the Child component again. |
| 159 | + act(() => { |
| 160 | + fireEvent.click(container.querySelector('button')); |
| 161 | + }); |
| 162 | + // Trigger Child update. |
| 163 | + act(() => { |
| 164 | + person.name = 'Ann'; |
| 165 | + }); |
| 166 | + |
| 167 | + expect(global.console.error.mock.calls.length).toBe(0); |
| 168 | + }); |
| 169 | + |
114 | 170 | test('view() should respect custom deriveStoresFromProps', () => { |
115 | 171 | const MyComp = view( |
116 | 172 | class extends Component { |
|
0 commit comments