Hi guys, today I'm going to talk about how to complete your code with one hook that will complete the puzzle!
The release of React 16.8 was a gift and a blessing, hooks were a great tool for managing the state of components. And having met with amicability, the community began to create new hooks based on standard ones for asynchronous operations, for interacting with external logic, and many many others.
Hooks let you use state and other React features without writing a class.
You can also build your own Hooks to share reusable stateful logic between components. (React website)
But (I'm sure) it became a chagrin for everyone that hooks can only store data at the component level. And therefore components can share their state only with children.
And that's the problem.
We have enough hooks to describe any logic, but there is no way to use their state together between a group of unrelated components.
You can see that Recoil, Redux, MobX, and the standard React hooks do the same thing - managing reactive state.
But why do we need to use in our applications a way of describing logic on hooks in components and on an external application state management system?
I suggest you try the simplest way to share the state described in hooks with other unrelated components on the page.
And this is just one hook, with the only one call argument - a custom hook, the result of which will be shared by everyone.
For example, let's describe a custom hook that supplies a hash from the browser's address bar. The hook subscribes to changes to the browser hash through the window
event.
// router.shared.ts
import { useState, useCallback, useEffect } from "react";
import { useBetween } from "use-between";
const useRouter = () => {
const [hash, setHash] = useState("");
const syncHash = useCallback(() => {
setHash(window.location.hash);
}, [setHash]);
useEffect(() => {
syncHash();
window.addEventListener("hashchange", syncHash);
return () => {
window.removeEventListener("hashchange", syncHash);
};
}, [syncHash]);
return {
hash
};
};
export const useSharedRouter = () => useBetween(useRouter);
In the last line of the example, we used a call to useBetween
passing a custom useRouter
hook as an argument, and thus created a new useSharedRouter
hook - a shared router for all components that will use it.
const Hash = () => {
const { hash } = useSharedRouter();
return (
<p>Location hash: {hash}</p>
)
}
export const App = () => (
<>
<Hash />
<Hash />
<Hash />
<a href="#hash-1">hash-1</a>
<a href="#hash-2">hash-2</a>
</>
)
In this example, the router will be created once and will be used for all the Hash
components. Every time the hash of the navigation bar address changes, all components using useSharedRouter
will be updated!
We used the standard React hooks that are familiar and understandable to everyone to create a shared state between any components using just one external hook useBetween
.
Everything will be installed simply npm i use-between
and you can use and enjoy, and for my taste, the easiest way to share the state in React!
If you like this idea and would like to use it, please put star in github. It will be your first contribution!
betula / use-between
Sharing state between React components
use-between
When you want to separate your React hooks between several components it's can be very difficult, because all context data stored in React component function area If you want to share some of state parts or control functions to another component your need pass It thought React component props. But If you want to share It with sibling one level components or a set of scattered components, you will be frustrated.
useBetween
hook is the solution to your problem π
import React, { useState, useCallback } from 'react';
import { useBetween } from 'use-between';
const useCounter = () => {
const [count, setCount] = useState(0);
const inc = useCallback(() => setCount(c => c + 1), []);
const dec = useCallback(() => setCount(c
β¦
Top comments (0)