{"push_id":2972473215,"size":4,"distinct_size":2,"ref":"refs/heads/strict-mode-suspense","head":"c463dfe72e381e813a6e00bb4305ff648bee3164","before":"1bb3110179ab59509188be99f70ee33a66ab14ed","commits":[{"sha":"7685b55d27c3932fd803230452cfd3d1ab076195","author":{"name":"Dan Abramov","email":"ffbbe9cb1097e7ea6a3dedffde5b4fe769829acc@gmail.com"},"message":"Remove unstable_read() in favor of direct dispatcher call (#13861)\n\n* Remove unstable_read() in favor of direct dispatcher call\r\n\r\n* This no longer throws immediately","distinct":false,"url":"https://api.github.com/repos/acdlite/react/commits/7685b55d27c3932fd803230452cfd3d1ab076195"},{"sha":"4f0bd45905b52b52406a006ccf42046828aa6bf2","author":{"name":"Pablo Javier D. A","email":"c253536d6a9edbccab40ee6b8f877020c07ba7ef@devpda.me"},"message":"Replacement of old links, by the new ones of the documentation. (#13871)","distinct":false,"url":"https://api.github.com/repos/acdlite/react/commits/4f0bd45905b52b52406a006ccf42046828aa6bf2"},{"sha":"dac9202a9c5add480f853bcad2ee04d371e72c0c","author":{"name":"Andrew Clark","email":"64b2b6d12bfe4baae7dad3d018f8cbf6b0e7a044@andrewclark.io"},"message":"Hide timed-out children instead of deleting them so their state is preserved (#13823)\n\n* Store the start time on `updateQueue` instead of `stateNode`\r\n\r\nOriginally I did this to free the `stateNode` field to store a second\r\nset of children. I don't we'll need this anymore, since we use fragment\r\nfibers instead. But I still think using `updateQueue` makes more sense\r\nso I'll leave this in.\r\n\r\n* Use fragment fibers to keep the primary and fallback children separate\r\n\r\nIf the children timeout, we switch to showing the fallback children in\r\nplace of the \"primary\" children. However, we don't want to delete the\r\nprimary children because then their state will be lost (both the React\r\nstate and the host state, e.g. uncontrolled form inputs). Instead we\r\nkeep them mounted and hide them. Both the fallback children AND the\r\nprimary children are rendered at the same time. Once the primary\r\nchildren are un-suspended, we can delete the fallback children — don't\r\nneed to preserve their state.\r\n\r\nThe two sets of children are siblings in the host environment, but\r\nsemantically, for purposes of reconciliation, they are two separate\r\nsets. So we store them using two fragment fibers.\r\n\r\nHowever, we want to avoid allocating extra fibers for every placeholder.\r\nThey're only necessary when the children time out, because that's the\r\nonly time when both sets are mounted.\r\n\r\nSo, the extra fragment fibers are only used if the children time out.\r\nOtherwise, we render the primary children directly. This requires some\r\ncustom reconciliation logic to preserve the state of the primary\r\nchildren. It's essentially a very basic form of re-parenting.\r\n\r\n* Use `memoizedState` to store various pieces of SuspenseComponent's state\r\n\r\nSuspenseComponent has three pieces of state:\r\n\r\n- alreadyCaptured: Whether a component in the child subtree already\r\nsuspended. If true, subsequent suspends should bubble up to the\r\nnext boundary.\r\n- didTimeout: Whether the boundary renders the primary or fallback\r\nchildren. This is separate from `alreadyCaptured` because outside of\r\nstrict mode, when a boundary times out, the first commit renders the\r\nprimary children in an incomplete state, then performs a second commit\r\nto switch the fallback. In that first commit, `alreadyCaptured` is\r\nfalse and `didTimeout` is true.\r\n- timedOutAt: The time at which the boundary timed out. This is separate\r\nfrom `didTimeout` because it's not set unless the boundary\r\nactually commits.\r\n\r\n\r\nThese were previously spread across several fields.\r\n\r\nThis happens to make the non-strict case a bit less hacky; the logic for\r\nthat special case is now mostly localized to the UnwindWork module.\r\n\r\n* Hide timed-out Suspense children\r\n\r\nWhen a subtree takes too long to load, we swap its contents out for\r\na fallback to unblock the rest of the tree. Because we don't want\r\nto lose the state of the timed out view, we shouldn't actually delete\r\nthe nodes from the tree. Instead, we'll keep them mounted and hide\r\nthem visually. When the subtree is unblocked, we un-hide it, having\r\npreserved the existing state.\r\n\r\nAdds additional host config methods. For mutation mode:\r\n\r\n- hideInstance\r\n- hideTextInstance\r\n- unhideInstance\r\n- unhideTextInstance\r\n\r\nFor persistent mode:\r\n\r\n- cloneHiddenInstance\r\n- cloneUnhiddenInstance\r\n- createHiddenTextInstance\r\n\r\nI've only implemented the new methods in the noop and test renderers.\r\nI'll implement them in the other renderers in subsequent commits.\r\n\r\n* Include `hidden` prop in noop renderer's output\r\n\r\nThis will be used in subsequent commits to test that timed-out children\r\nare properly hidden.\r\n\r\nAlso adds getChildrenAsJSX() method as an alternative to using\r\ngetChildren(). (Ideally all our tests would use test renderer #oneday.)\r\n\r\n* Implement hide/unhide host config methods for DOM renderer\r\n\r\nFor DOM nodes, we hide using `el.style.display = 'none'`.\r\n\r\nText nodes don't have style, so we hide using `text.textContent = ''`.\r\n\r\n* Implement hide/unhide host config methods for Art renderer\r\n\r\n* Create DOM fixture that tests state preservation of timed out content\r\n\r\n* Account for class components that suspend outside concurrent mode\r\n\r\nNeed to distinguish mount from update. An unfortunate edge case :(\r\n\r\n* Fork appendAllChildren between persistent and mutation mode\r\n\r\n* Remove redundant check for existence of el.style\r\n\r\n* Schedule placement effect on indeterminate components\r\n\r\nIn non-concurrent mode, indeterminate fibers may commit in an\r\ninconsistent state. But when they update, we should throw out the\r\nold fiber and start fresh. Which means the new fiber needs a\r\nplacement effect.\r\n\r\n* Pass null instead of current everywhere in mountIndeterminateComponent","distinct":true,"url":"https://api.github.com/repos/acdlite/react/commits/dac9202a9c5add480f853bcad2ee04d371e72c0c"},{"sha":"c463dfe72e381e813a6e00bb4305ff648bee3164","author":{"name":"Andrew Clark","email":"2acf6cde80014901295f159e9eeaed48c8126d4e@fb.com"},"message":"Strict mode and default mode should have same Suspense semantics\n\nIn the default mode, Suspense has special semantics where, in\naddition to timing out immediately, we don't unwind the stack before\nrendering the fallback. Instead, we commit the tree in an inconsistent\nstate, then synchronous render *again* to switch to the fallback. This\nis slower but is less likely to cause issues with older components that\nperform side effects in the render phase (e.g. componentWillMount,\ncomponentWillUpdate, and componentWillReceiveProps).\n\nWe should do this in strict mode, too, so that there are no semantic\ndifferences (in prod, at least) between default mode and strict mode.\nThe rationale is that it makes it easier to wrap a tree in strict mode\nand start migrating components incrementally without worrying about new\nbugs in production.","distinct":true,"url":"https://api.github.com/repos/acdlite/react/commits/c463dfe72e381e813a6e00bb4305ff648bee3164"}]}
{"actor":{"display_login":"acdlite"}}