Replies: 2 comments 2 replies
-
Thanks for starting this discussion Thomas. Made it through the Concurrent Mode Patterns article. Big read. My impression is that we'd best off completely avoiding creating components just to wrap the
Further, its inline with some of the docs examples, like: function ProfilePage({ resource }) {
return (
<>
<ProfileDetails resource={resource} />
<Suspense fallback={<h2>Loading posts...</h2>}>
<ProfileTimeline resource={resource} />
</Suspense>
<Suspense fallback={<h2>Loading fun facts...</h2>}>
<ProfileTrivia resource={resource} />
</Suspense>
</>
);
} Per the example above, I'd suggest simply removing the component completely: const SendButtonFallback = memo(() => (
<TxButton isDisabled path={ScreenPaths.POPUP_SEND} kind="send"/>
));
const SendButton = () => {
const assets = useTransferableAssets(); // an async atom
const isDisabled = !assets || assets?.length === 0;
return <TxButton isDisabled={isDisabled} path={ScreenPaths.POPUP_SEND} kind="send"/>;
};
export const HomeActions = props => {
return (
<Stack>
<React.Suspense fallback={<SendButtonFallback />}>
<SendButton />
</React.Suspense>
<TxButton path={ScreenPaths.POPUP_RECEIVE} kind="receive" />
</Stack>
);
}; By omitting the component that only handles the suspense boundary, we solve this naming paradox completely. Plus, in none of the react doc examples do they declare a component suspends by naming it with a suffix. So there's no precedent to do this, and I think this is intentional. A component doesn't need to expose its implementation details (that it suspends). My point boils down to: I think we should postpone adding this abstraction. Perhaps we do need it. Maybe we don't. But it's easier to add an abstraction later, than remove it later, imo. |
Beta Was this translation helpful? Give feedback.
-
As far as I know, Suspense is an experimental feature, not supported by React yet and in a version that we don't use. I'd rather park this discussion until we see a need for performance improvements that suspense would help with. What do you think? |
Beta Was this translation helpful? Give feedback.
-
Continued from https://github.com/blockstack/stacks-wallet-web/pull/1326/files/922891daedaea060bd3d603d25e2e29f12f8664f#r655165139
With the refactor away from recoil over to jotai, we now are using
Suspense
in a much more direct and impactful way. We previously had a few instances where async atoms were used in components that required being wrapped in a Suspense boundary, but recoil had theLoadable
concept which converts a suspense atom to one that wouldn't suspend. Jotai does not have this same concept.Before digging in, I'd highly recommend reading these so we are all at a similar place when it comes to context around what suspense/concurrent mode is, and how it's used related to data fetching.
https://reactjs.org/docs/concurrent-mode-suspense.html
https://reactjs.org/docs/concurrent-mode-patterns.html
reactwg/react-18#61 (read as many of these discussions as you can, very helpful!)
During my refactor PR, I ran into the situation where we have components that are async, require a fallback, and could be wrapped in an error boundary. Take this component as an example:
To me, for any given "async" component, there will be a few different parts:
The reason I defaulted to naming the suspending component with a suffix of
Suspense
is because I think it's important to know by seeing the component name that it will suspend, where if we useSendButton
, a developer can be free to place it anywhere.Here is what @kyranjamie suggested:
The other thing to consider is it will be more and more common for most of our components to be async as time goes on, and I wonder if we need to even consider this kind of naming convention at all. FB has been using these patterns for a long time, and there is never anything done like this. (They just name them what they are, and wrap them as needed)
What does everyone think?
Beta Was this translation helpful? Give feedback.
All reactions