Skip to content

Instantly share code, notes, and snippets.

@anaisbetts
Created January 13, 2019 05:12
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anaisbetts/78189082b18db318bcc15012c9ad58e6 to your computer and use it in GitHub Desktop.
Save anaisbetts/78189082b18db318bcc15012c9ad58e6 to your computer and use it in GitHub Desktop.
import { Model } from '@whenjs/when';
import { useState } from 'react';
import { useWhen } from '../src/when-react/use-helpers';
class ViewModel extends Model {
public foo: number;
constructor() {
super();
this.propertyShouldNotify('foo');
this.foo = 1;
}
}
function Example() {
const [vm] = useState(new ViewModel());
const num = useWhen(vm, x => x.foo);
return (
<div>
<p>You clicked {num} times</p>
<button onClick={() => (vm.foo += 1)}>Click me</button>
</div>
);
}
export default () => {
const [clicked, setClick] = useState(false);
if (clicked) {
return <div>deaded.</div>;
}
return (
<div>
<Example />
<button onClick={() => setClick(true)}>unmount</button>
</div>
);
};
import { getValue, when } from '@whenjs/when';
import { useEffect, useState } from 'react';
import { Observable } from 'rxjs';
export type PropSelector<TIn, TOut> = ((t: TIn) => TOut);
export function useObservable<T>(target: () => Observable<T>, initial: T) {
const [ret, setter] = useState(initial);
const [obs] = useState(target());
useEffect(
() => {
const sub = obs.subscribe(setter);
return sub.unsubscribe.bind(sub);
},
[obs]
);
return ret;
}
export function useWhen<TSource, TRet>(
model: TSource,
prop: PropSelector<TSource, TRet>
): TRet {
return useObservable(() => when(model, prop), getValue(model, prop).result!);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment