|
1 | | -import React, { Fragment, Component, createElement, createContext, useContext, useState } from 'react' |
| 1 | +import React, { |
| 2 | + Fragment, |
| 3 | + Component, |
| 4 | + createElement, |
| 5 | + createContext, |
| 6 | + useContext, |
| 7 | + useState, |
| 8 | + useMemo, |
| 9 | + useRef |
| 10 | +} from 'react' |
2 | 11 |
|
3 | 12 | import renderPrepass from '..' |
4 | 13 |
|
@@ -44,6 +53,36 @@ describe('renderPrepass', () => { |
44 | 53 | }) |
45 | 54 | }) |
46 | 55 |
|
| 56 | + it('preserves state correctly across suspensions', () => { |
| 57 | + const getValue = jest.fn() |
| 58 | + .mockImplementationOnce(() => { throw Promise.resolve() }) |
| 59 | + .mockImplementation(() => 'test') |
| 60 | + |
| 61 | + const Inner = jest.fn(props => { |
| 62 | + expect(props.value).toBe('test') |
| 63 | + expect(props.state).toBe('test') |
| 64 | + }) |
| 65 | + |
| 66 | + const Outer = jest.fn(() => { |
| 67 | + const [state, setState] = useState('default') |
| 68 | + |
| 69 | + const memoed = useMemo(() => state, [state]) |
| 70 | + const ref = useRef('initial') |
| 71 | + expect(memoed).toBe(state) |
| 72 | + expect(ref.current).toBe('initial') |
| 73 | + |
| 74 | + const value = getValue() |
| 75 | + setState(value) |
| 76 | + |
| 77 | + return <Inner value={value} state={state} /> |
| 78 | + }) |
| 79 | + |
| 80 | + return renderPrepass(<Outer />).then(() => { |
| 81 | + expect(Outer).toHaveBeenCalledTimes(3 * 3 * 3 /* welp */) |
| 82 | + expect(Inner).toHaveBeenCalledTimes(2) |
| 83 | + }) |
| 84 | + }) |
| 85 | + |
47 | 86 | it('ignores thrown non-promises', () => { |
48 | 87 | const Outer = () => { throw new Error('test') } |
49 | 88 | const render$ = renderPrepass(<Outer />) |
|
0 commit comments