| 1 | let React; |
| 2 | let ReactNoop; |
| 3 | let Scheduler; |
| 4 | let act; |
| 5 | let assertLog; |
| 6 | |
| 7 | describe('ReactClassSetStateCallback', () => { |
| 8 | beforeEach(() => { |
| 9 | jest.resetModules(); |
| 10 | |
| 11 | React = require('react'); |
| 12 | ReactNoop = require('react-noop-renderer'); |
| 13 | Scheduler = require('scheduler'); |
| 14 | act = require('internal-test-utils').act; |
| 15 | |
| 16 | const InternalTestUtils = require('internal-test-utils'); |
| 17 | assertLog = InternalTestUtils.assertLog; |
| 18 | }); |
| 19 | |
| 20 | function Text({text}) { |
| 21 | Scheduler.log(text); |
| 22 | return text; |
| 23 | } |
| 24 | |
| 25 | it('regression: setState callback (2nd arg) should only fire once, even after a rebase', async () => { |
| 26 | let app; |
| 27 | class App extends React.Component { |
| 28 | state = {step: 0}; |
| 29 | render() { |
| 30 | app = this; |
| 31 | return <Text text={this.state.step} />; |
| 32 | } |
| 33 | } |
| 34 | |
| 35 | const root = ReactNoop.createRoot(); |
| 36 | await act(() => { |
| 37 | root.render(<App />); |
| 38 | }); |
| 39 | assertLog([0]); |
| 40 | |
| 41 | await act(() => { |
| 42 | React.startTransition(() => { |
| 43 | app.setState({step: 1}, () => Scheduler.log('Callback 1')); |
| 44 | }); |
| 45 | ReactNoop.flushSync(() => { |
| 46 | app.setState({step: 2}, () => Scheduler.log('Callback 2')); |
| 47 | }); |
| 48 | }); |
| 49 | assertLog([2, 'Callback 2', 2, 'Callback 1']); |
| 50 | }); |
| 51 | }); |