Last active
March 21, 2019 19:35
-
-
Save tonyonodi/675d14f8e7e3218d32511ee585a27fa0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as React from "react"; | |
import { interval, Observable, fromEvent, merge } from "rxjs"; | |
import { map, scan, mapTo } from "rxjs/operators"; | |
const { useState, useEffect, useRef } = React; | |
function useStream<T>(streamContainer: () => Observable<T>, initialValue: T) { | |
const [state, setState] = useState(initialValue); | |
useEffect(() => { | |
const stream = streamContainer(); | |
stream.subscribe((val: any) => { | |
setState(val); | |
}); | |
}, []); | |
return state; | |
} | |
const myStreamContainer = (button: React.RefObject<HTMLButtonElement>) => () => { | |
const timer = interval(1000).pipe( | |
map(t => { | |
return { time: t }; | |
}) | |
); | |
const clickStream = fromEvent( | |
button.current as HTMLButtonElement, | |
"click" | |
).pipe( | |
mapTo(1), | |
scan((acc, one) => acc + one, 0), | |
map(cCount => ({ clickCount: cCount })) | |
); | |
return merge(timer, clickStream).pipe( | |
scan((prevState, evt) => ({ ...prevState, ...evt }), { | |
time: 0, | |
clickCount: 0, | |
}) | |
); | |
}; | |
function App() { | |
const button = useRef<HTMLButtonElement>(null); | |
const { time, clickCount } = useStream(myStreamContainer(button), { | |
time: 0, | |
clickCount: 0, | |
}); | |
return ( | |
<div> | |
<button ref={button}>Click me</button> | |
<p> | |
You have clicked the button {clickCount} times in {time} seconds. | |
</p> | |
</div> | |
); | |
} | |
export default App; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment