react-mut
v1.0.1
Published
π Subscribe components to any object.
Downloads
7
Maintainers
Readme
React Mut
π Subscribe component to any object.
Click here to see sandbox.
Basics
Subscribe with useMut
β Mutate object β Notify subscribers with mut
import { mut, useMut } from 'react-mut';
const mutableObject = { title: 'title' };
const Component = () => {
// subscribe
useMut(mutableObject);
return (
<button
onClick={() => {
// mutate and notify subscribers
mut(mutableObject).title = 'next title';
}}
>
{mutableObject.title}
</button>
);
};
Mutations
You can mark objects as mutated with mut
.
You can call mut
anytime (before mutation and after mutation).
import { mut } from 'react-mut';
const mutableObject = { title: 'title' };
// before mutation:
mut(mutableObject).title = 'next title';
// or after mutation:
mutableObject.title = 'next title';
mut(mutableObject);
// this will work too:
Object.assign(mut(mutableObject), {
title: 'next title',
});
Notifying subscribers scheduled via microtask.
But you can immediately notify subscribers with sync
.
It can be useful for tests, for example.
import { sync } from 'react-mut';
const mutableObject = { title: 'title' };
const action = () => {
mut(mutableObject).title = 'next title';
// immediately notify subscribers
sync();
};
Versions
When you call mut
with object, object's version updated.
You can read object's version with ver
.
It can be useful for hook's dependencies, for example.
import { mut, useMut } from 'react-mut';
const mutableObject = { title: 'title' };
const Component = () => {
useMut(mutableObject);
useEffect(() => {
// Will be logged on button below click
console.log(mutableObject);
}, [ver(mutableObject)]);
return (
<button
onClick={() => {
mut(mutableObject).title = 'next title';
}}
>
{mutableObject.title}
</button>
);
};
Subscriptions
You can subscribe to object with sub
.
You can unsubscribe from object with returned callback.
import { sub, mut } from 'react-mut';
const mutableObject = { title: 'title' };
const unsubscribe = sub(mutableObject, () => {
// will be logged on mutableObject's version change.
console.log(mutableObject);
});
unsubscribe();
You also can unsubscribe from object with unsub
.
You can unsubscribe all from object with unsub
without callback.
import { unsub, sub, mut } from 'react-mut';
const mutableObject = { title: 'title' };
const callback = () => {
// will be logged on mutableObject's version change.
console.log(mutableObject);
};
// subscribe callback to mutableObject
sub(mutableObject, callback);
// unsubscribe callback from mutableObject
unsub(mutableObject, callback);
// subscribe anonymus callback to mutableObject
sub(mutableObject, () => {
console.log(mutableObject);
});
// unsubscribe all callbacks from mutableObject
unsub(mutableObject);
Hooks
You can use useMut
to subscribe component to object.
Component will be re-rendered after mut
call with object.
import { mut, useMut } from 'react-mut';
const mutableObject = { title: 'title' };
// Will be re-rendered on mutableObject's version change
const Component = () => {
const mutableObject = useMut(mutableObject);
return <div>{mutableObject.title}</div>;
};
// Will be re-rendered on mutableObject.title change
const AnotherComponent = () => {
const title = useMut(mutableObject, () => title);
return <div>{title}</div>;
};
You can use selectors with useSel
to optimize re-renders.
Selector will be called after mut
call with any object.
Component will be re-rendered if selected value changed.
import { mut, useSel } from 'react-mut';
const mutableObject = { title: 'title' };
// Will be re-rendered on mutableObject.title change
const Component = () => {
const title = useSel(() => mutableObject.title);
return <div>{title}</div>;
};
Also, you can use useMutSel
for subscribing to nested mutable objects.
Selector will be called after mut
call with any object.
It's alias for useMut(useSel(...))
;
import { mut, useMutSel } from 'react-mut';
const items = [{ title: 'title' }];
// Will be re-rendered on items[0]'s version change
const Component = () => {
const item = useMutSel(() => items[0]);
return <div>{item.title}</div>;
};