Loading data inside of hooks VS loading data outside of hooks?
- Dominant language
- Rust
- Stars
- 19k
- Forks
- 1.9k
- PR merge metrics
- No merged PRs in 30d
Description
Related Loom discussing an internal PR: https://www.loom.com/share/670823d870084f7b920d368802463761
Would love to have some input from Relay's team about the best practices here.
TLDR is that we want to standardize how we fetch data and we are debating between 2 patterns:
## Loading data inside of hooks
```ts
export const useCopyProfileUrl = ({
userProfileRef,
utmTag,
}: {
userProfileRef: useCopyProfileUrl_userProfile$key;
utmTag?: {
utm_campaign: string;
utm_medium: string;
utm_source: string;
};
}) => {
const userProfile = useFragment(
graphql`
fragment useCopyProfileUrl_userProfile on UserProfile {
displayUsername
}
`,
userProfileRef,
);
// [..]
```
* Pro: data fetching is co-localized with consumption. In theory, if Relay ESLint plugin worked, this would provide us protection against data over-fetching.
* Con: need to add `useCopyProfileUrl_userProfile` fragment to every parent data loader/fragment
* Con: additional suspense may cause unexpected issues with state management [components losing internal state]
* Con: a bit harder to test
## Loading data outside of hooks
```ts
const profile = useFragment(
graphql`
fragment ShareProfileMenuButton_userProfile on UserProfile {
displayUsername
}
`,
userProfileRef,
);
const { onCopyProfileLink } = useCopyProfileUrl({
userProfile: {
displayUsername: profile.displayUsername,
},
utmTag: {
utm_campaign: 'social_sharing',
utm_medium: 'independent_share',
utm_source: 'copy_link',
},
});
```
* Pro: encapsulation
* Pro: portability
* Pro: ease of testing
* Con: the need to explicitly map every property (if we want to retain static analyzes for over-fetching protection)
* Con: easy to over-fetch since the former cannot be enforced
What's the recommended path and what are your arguments for it?
Contributor guide
Assessment
This issue has not been assessed yet.