https://github.com/cawfree/use-merge
⚛️ 💡 Simplify the relationships between multiple hooks.
https://github.com/cawfree/use-merge
combine hooks merge react react-native synchronize
Last synced: about 1 year ago
JSON representation
⚛️ 💡 Simplify the relationships between multiple hooks.
- Host: GitHub
- URL: https://github.com/cawfree/use-merge
- Owner: cawfree
- License: mit
- Created: 2020-10-26T22:59:57.000Z (over 5 years ago)
- Default Branch: main
- Last Pushed: 2020-10-30T02:04:25.000Z (over 5 years ago)
- Last Synced: 2025-03-18T15:47:14.015Z (over 1 year ago)
- Topics: combine, hooks, merge, react, react-native, synchronize
- Language: TypeScript
- Homepage:
- Size: 326 KB
- Stars: 6
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# use-merge
Simplify the relationships between multiple hooks.
### 🚀 Getting Started
Using [**Yarn**](https://yarnpkg.com):
```sh
yarn add use-merge
```
### 😲 Everything and your mother is a hook now.
Functional components are becoming increasingly complex; the wide availability of capable hooks and their applicability to the management of application state logic has made it commonplace to embed multiple hooks in a single component. Depending on the availability of asynchronous data, hooks can easily become desynchronized with one-another and necessitate multiple render lifecycles in order to harmonize.
What's worse, is that hooks dependent on the output of previously declared hooks require non-trivial and repetitive manual management of loading and error states to manage the render result.
**Take the following:**
```javascript
import { ActivityIndicator } from "react-native";
import { useQuery, gql } from "@apollo/graphql";
import { DataComponent, ErrorComponent } from ".";
export default function SomeComponent() {
const { loading: loadingA, error: errorA, data: dataA } = useQuery(gql`...`);
const { loading: loadingB, error: errorB, data: dataB } = useQuery(gql`...`);
const { loading: loadingC, error: errorC, data: dataC } = useQuery(gql`...`);
const loading = loadingA || loadingB || loadingC;
const error = errorA || errorB || errorC; // Not to mention, this swallows errors...
if (loading) {
return ;
} else if (error) {
return ;
}
return ;
}
```
> We've all seen it. And it's becoming increasingly more common as hooks get ever more awesome.
### 🤔 So... what's the answer to the problem of multiple hooks? Why, a hook of course!
With `use-merge`, you can combine the outputs of multiple hooks _and_ synchronize their requests to re-render:
```javascript
import { ActivityIndicator } from "react-native";
import { useQuery, gql } from "@apollo/graphql";
import useMerge, { By } from "use-merge";
import { DataComponent, ErrorComponent } from ".";
export default function SomeComponent() {
const { a, b, c, merged: { loading, error } } = useMerge({
a: useQuery(gql`...`),
b: useQuery(gql`...`),
c: useQuery(gql`...`),
})({ loading: By.Truthy, error: By.Error });
if (loading) {
return ;
} else if (error) {
return ;
}
return ;
}
```
This makes it much simpler, consistent and more efficient to handle the processing of multiple hooks within the scope of a single function.
### 🤔 What about hooks which are dependent upon the output of others?
We got you covered. Pass a `function` into `useMerge` to retrieve the last merged state. This is also exported alongside [`lodash.get`](https://lodash.com/docs/4.17.15#get) so you can safely interrogate deeply-nested, potentially uninitialized, objects.
```javascript
const { a, b, c, merged: { loading, error } } = useMerge(({ a }, get) => ({
a: useQuery(gql`...`),
b: useQuery(gql`...`),
c: useQuery(gql`...${get(a, 'data.id')}`),
}))({ loading: By.Truthy, error: By.Error });
```
## ✌️ License
[**MIT**](./LICENSE)