Skip to content

Commit 087a346

Browse files
authored
[test] add activity test with gSBU and enableViewTransition bugfix (facebook#35555)
Related to facebook#35548, `enableViewTransition` fixes a bug where `getSnapshotBeforeUpdate` was running in hidden trees when it shouldn't (`componentWillUpdate` won't run for hidden updates, and when it becomes visible it will be called with `componentWillMount`).
1 parent 6913ea4 commit 087a346

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

packages/react-reconciler/src/__tests__/Activity-test.js

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,6 +1527,87 @@ describe('Activity', () => {
15271527
expect(root).toMatchRenderedOutput(<span prop={2} />);
15281528
});
15291529

1530+
// @gate enableActivity
1531+
it('getSnapshotBeforeUpdate does not run in hidden trees', async () => {
1532+
let setState;
1533+
1534+
class Child extends React.Component {
1535+
getSnapshotBeforeUpdate(prevProps) {
1536+
const snapshot = `snapshot-${prevProps.value}-to-${this.props.value}`;
1537+
Scheduler.log(`getSnapshotBeforeUpdate: ${snapshot}`);
1538+
return snapshot;
1539+
}
1540+
componentDidUpdate(prevProps, prevState, snapshot) {
1541+
Scheduler.log(`componentDidUpdate: ${snapshot}`);
1542+
}
1543+
componentDidMount() {
1544+
Scheduler.log('componentDidMount');
1545+
}
1546+
componentWillUnmount() {
1547+
Scheduler.log('componentWillUnmount');
1548+
}
1549+
render() {
1550+
Scheduler.log(`render: ${this.props.value}`);
1551+
return <span prop={this.props.value} />;
1552+
}
1553+
}
1554+
1555+
function Wrapper({show}) {
1556+
const [value, _setState] = useState(1);
1557+
setState = _setState;
1558+
return (
1559+
<Activity mode={show ? 'visible' : 'hidden'}>
1560+
<Child value={value} />
1561+
</Activity>
1562+
);
1563+
}
1564+
1565+
const root = ReactNoop.createRoot();
1566+
1567+
// Initial render
1568+
await act(() => {
1569+
root.render(<Wrapper show={true} />);
1570+
});
1571+
assertLog(['render: 1', 'componentDidMount']);
1572+
1573+
// Hide the Activity
1574+
await act(() => {
1575+
root.render(<Wrapper show={false} />);
1576+
});
1577+
assertLog([
1578+
'componentWillUnmount',
1579+
'render: 1',
1580+
// Bugfix: snapshots for hidden trees should not need to be read.
1581+
...(gate('enableViewTransition')
1582+
? []
1583+
: ['getSnapshotBeforeUpdate: snapshot-1-to-1']),
1584+
]);
1585+
1586+
// Trigger an update while hidden by calling setState
1587+
await act(() => {
1588+
setState(2);
1589+
});
1590+
assertLog([
1591+
'render: 2',
1592+
...(gate('enableViewTransition')
1593+
? []
1594+
: ['getSnapshotBeforeUpdate: snapshot-1-to-2']),
1595+
]);
1596+
1597+
// This is treated as a new mount so the snapshot also shouldn't be read.
1598+
await act(() => {
1599+
root.render(<Wrapper show={true} />);
1600+
});
1601+
assertLog([
1602+
'render: 2',
1603+
...(gate('enableViewTransition')
1604+
? []
1605+
: ['getSnapshotBeforeUpdate: snapshot-2-to-2']),
1606+
'componentDidMount',
1607+
]);
1608+
});
1609+
1610+
// @gate enableActivity
15301611
it('warns if you pass a hidden prop', async () => {
15311612
function App() {
15321613
return (

0 commit comments

Comments
 (0)