Share state between React components using custom hooks and observables
nikita
Posted on April 13, 2021
React custom hooks are a powerful feature that provide a handy way to organize and reuse logic in a simple functional manner. And mixing them with observables allows us to solve one of the most common problems in a Single Page Apps - state management.
Firstly we need to create some basic observable implementation:
function makeObservable(target) {
let listeners = []; // initial listeners can be passed an an argument aswell
let value = target;
function get() {
return value;
}
function set(newValue) {
if (value === newValue) return;
value = newValue;
listeners.forEach((l) => l(value));
}
function subscribe(listenerFunc) {
listeners.push(listenerFunc);
return () => unsubscribe(listenerFunc); // will be used inside React.useEffect
}
function unsubscribe(listenerFunc) {
listeners = listeners.filter((l) => l !== listenerFunc);
}
return {
get,
set,
subscribe,
};
}
And then create a store and hook it to React by using subscribe in useEffect:
const userStore = makeObservable({ name: "user", count: 0 });
const useUser = () => {
const [user, setUser] = React.useState(userStore.get());
React.useEffect(() => {
return userStore.subscribe(setUser);
}, []);
const actions = React.useMemo(() => {
return {
setName: (name) => userStore.set({ ...user, name }),
incrementCount: () => userStore.set({ ...user, count: user.count + 1 }),
decrementCount: () => userStore.set({ ...user, count: user.count - 1 }),
}
}, [user])
return {
state: user,
actions
}
}
And that is it! You can now use useUser
hook in any of your components, trigger related actions and be sure that state
is always up to date. No need for React.Context
, lifting state up or using external state management tool.
Let me know what you think and thanks for reading.
Posted on April 13, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.