From 28ab856b36a9eef8b7d4d4bd7f19ec3f44b07c43 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Sat, 30 Jan 2021 15:36:42 -0600 Subject: [PATCH] Concurrent Mode test for uMS render mutation Same test as the one added in #20665, but for Concurrent Mode. --- .../useMutableSource-test.internal.js | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js b/packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js index 243232f1b83bf..6807bc7034848 100644 --- a/packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js +++ b/packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js @@ -1724,6 +1724,56 @@ describe('useMutableSource', () => { describe('side effecte detection', () => { // @gate experimental it('should throw if a mutable source is mutated during render', () => { + const source = createSource(0); + const mutableSource = createMutableSource( + source, + param => param.version, + ); + + let mutatedValueInRender = 1; + function MutateDuringRead() { + const value = useMutableSource( + mutableSource, + defaultGetSnapshot, + defaultSubscribe, + ); + Scheduler.unstable_yieldValue('MutateDuringRead:' + value); + // Note that mutating an exeternal value during render is a side effect and is not supported. + source.value = mutatedValueInRender++; + return null; + } + + expect(() => { + expect(() => { + act(() => { + ReactNoop.render(); + }); + }).toThrow( + 'Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue.', + ); + }).toWarnDev([ + // Warns twice because of the retry-on-error render pass. Should + // consider only warning during the first attempt, not during the + // retry. Or maybe vice versa. + 'A mutable source was mutated while the MutateDuringRead component was rendering. This is not supported. ' + + 'Move any mutations into event handlers or effects.\n' + + ' in MutateDuringRead (at **)', + 'A mutable source was mutated while the MutateDuringRead component was rendering. This is not supported. ' + + 'Move any mutations into event handlers or effects.\n' + + ' in MutateDuringRead (at **)', + ]); + + expect(Scheduler).toHaveYielded([ + // First attempt + 'MutateDuringRead:0', + + // Synchronous retry + 'MutateDuringRead:1', + ]); + }); + + // @gate experimental + it('should throw if a mutable source is mutated during render (legacy mode)', () => { const source = createSource('initial'); const mutableSource = createMutableSource( source,