The idea I started with is: What if we could write state changes in react as mutations on a persistent reference? 🤔 So I wrote the code to make it work! The basic concept is summed up in the code from the banner image:
import React from 'react';
import { useObject } from '../hooks/useObject';
export const Counter: React.FC = () => {
const [state] = useObject({
count: 1,
});
return (
<button
onClick={() => {
state.count++;
}}
>
{state.count}
</button>
);
};
In this case, state is a persistent reference that you can mutate (state.count++
). The consequences of this change are fairly interesting. For one, you can create these objects with a class! So the above example could be rewritten as:
import React from 'react';
import { useInstance } from '../hooks/useInstance';
class Counter {
count = 1;
increment() {
this.count++;
}
}
export const Counter: React.FC = () => {
const [counter] = useInstance(Counter);
return (
<button
onClick={() => {
counter.increment();
}}
>
{counter.count}
</button>
);
};
Also, if you need to subscribe to to changes in the objects outside of a component function, they implement the AsyncIterable
interface, so you can await
their next state, or for await
future states in an async
function. Here's a logger class that subscribes to a counter!
class CounterLogger {
constructor(
private counter: Counter & AsyncIterable<Counter>
) {}
log(count: number) {
console.log(`Count is: ${count}`);
}
async watch() {
this.log(this.counter.count);
for await (const { count } of this.counter) {
this.log(count);
}
}
}
There's more to it, and there will be more as the project progresses. I wanted to share what I have in its current "state" 😉 to give everyone a chance to contribute their thoughts and ideas! If you're interested, clone the repo and try it for yourself! Or leave a comment or question on this post! All are contributions, all are welcome. 🔰