@@ -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