hookstate
hookstate copied to clipboard
Partial Updates (Scoped State) with Classes
Is there a way to get partial updates working when using classes instead of plain objects?
Consider the following example:
import React from 'react';
import { useHookstate } from "@hookstate/core";
class AppState {
constructor() {
this.a = 0;
this.b = 0;
}
}
export function App() {
const state = useHookstate(new AppState())
return (
<div>
<p>{new Date().toISOString().toString()}: {state.a.get()}</p>
<Component count={state.b} />
</div>
);
}
function Component(props) {
const count = useHookstate(props.count)
return (
<>
<p>{new Date().toISOString().toString()}: {count.get()}</p>
<button onClick={() => count.set(count => count + 1)}>Count</button>
</>
);
}
Here, both the parent component and the child component get updated when the button is clicked. When new AppState()
is replaced with { a: 0, b: 0 }
, only the child component gets updated. Is there a way to get the behavior from the plain object state while using a class object? I'm fully aware that Hookstate won't be able to catch every update when more advanced class features like getters and methods are used, but I'm willing to handle these cases myself.
I would like to use Hookstate to model the UI around an existing app state instead of duplicating the state for the UI, but this won't work if on every change the whole UI gets updated. Most of the app state behaves like a plain object, the class is mostly used for data validation and stuff like that.
The documentation of Hookstate says, that for non-plain objects, get()
gets replaced with get({ noproxy: true })
. I'm fine with that, but I think in the example above something else is going on because when I replace new AppState()
with { a: 0, b: 0 }
and both get
calls with get({ noproxy: true })
, the partial update still works.
Example Class State: https://playcode.io/1047463
Example Plain Object State: https://playcode.io/1047469
Example Plain Object State with { noproxy: true }
: https://playcode.io/1047470
Theoretically, it could be possible to implement a new option for configure function, which would allow to define callback, which would define per each variable of a custom class if it should be returned as a proxy or not. Then this callback could be invoked on get where it tests Object's class name. Very easy addition, please consider to contribute. I will help.