Skip to content

Instantly share code, notes, and snippets.

@anaisbetts
Created January 13, 2019 04:49
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/1ed380401843210b104e587970ec2fe7 to your computer and use it in GitHub Desktop.
Save anaisbetts/1ed380401843210b104e587970ec2fe7 to your computer and use it in GitHub Desktop.
RxJS + React Hooks
import { Model, when } from '@whenjs/when';
import { scan } from 'rxjs/operators';
import { useState } from 'react';
import { useObservable } from '../src/when-react/use-helpers';
class ViewModel extends Model {
public foo: number;
constructor() {
super();
this.propertyShouldNotify('foo');
this.foo = 0;
}
}
function Example() {
const [vm] = useState(new ViewModel());
const obs = when(vm, x => x.foo).pipe(scan(acc => acc * 2, 1));
const num = useObservable(obs, 0, vm);
return (
<div>
<p>You clicked 2^{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 { useEffect, useState } from 'react';
import { Observable } from 'rxjs';
function findObservableSourceViaShadyTrickz<T>(target: Observable<T>): any {
let ret: any = target;
while (ret.source) {
ret = ret.source;
}
return ret;
}
export function useObservable<T>(
target: Observable<T>,
initial: T,
source: any = null
) {
const [ret, setter] = useState(initial);
const src = source || findObservableSourceViaShadyTrickz(target);
useEffect(
() => {
const sub = target.subscribe(setter);
return sub.unsubscribe.bind(sub);
},
[src]
);
return ret;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment