From 6ec4e8f01aec6717d65be3be93a4693e51595473 Mon Sep 17 00:00:00 2001 From: Jerry Zou Date: Mon, 26 Nov 2018 11:26:25 +0800 Subject: [PATCH] doc: update readme document for v0.2 --- README.md | 174 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 156 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 6dd5328a..a55f2cc5 100644 --- a/README.md +++ b/README.md @@ -77,11 +77,13 @@ function App() { ### `useObservable` ```tsx -declare function useObservable(sourceFactory: () => Observable): T | null +declare type InputFactory = U extends undefined + ? (state$: Observable) => Observable + : (inputs$: Observable, state$: Observable) => Observable -declare function useObservable(sourceFactory: () => Observable, initialState: T): T - -declare function useObservable(sourceFactory: (inputs$: Observable) => Observable, initialState: T, inputs: U): T +declare function useObservable(inputFactory: InputFactory): T | null +declare function useObservable(inputFactory: InputFactory, initialState: T): T +declare function useObservable(inputFactory: InputFactory, initialState: T, inputs: U): T ``` #### Examples: @@ -147,24 +149,62 @@ ReactDOM.render(, document.querySelector('#app')) ReactDOM.render(, document.querySelector('#app')) ``` +**useObservable with state$** + +[live demo](https://codesandbox.io/s/7jwv36w876) + +```tsx +import React from 'react' +import ReactDOM from 'react-dom' +import { useObservable } from 'rxjs-hooks' +import { interval } from 'rxjs' +import { map, withLatestFrom } from 'rxjs/operators' + +function App() { + const value = useObservable((state$) => interval(1000).pipe( + withLatestFrom(state$), + map(([_num, state]) => state * state), + ), 2) + return ( + // 2 + // 4 + // 16 + // 256 + // ... +

{value}

+ ) +} + +ReactDOM.render(, document.querySelector('#root')) +``` + ### `useEventCallback` ```tsx -declare type EventCallbackState = [ - ((e: SyntheticEvent) => void) | typeof noop, - U +declare type VoidAsNull = T extends void ? null : T + +declare type EventCallbackState<_T, E, U, I = void> = [ + (e: E) => void, + [U extends void ? null : U, BehaviorSubject, BehaviorSubject] ] -declare type EventCallback = ( - eventSource$: Observable> -) => Observable - -declare function useEventCallback( - callback: EventCallback -): EventCallbackState -declare function useEventCallback( - callback: EventCallback, - initialState: U -): EventCallbackState +declare type ReturnedState = [EventCallbackState[0], EventCallbackState[1][0]] + +declare type EventCallback<_T, E, U, I> = I extends void + ? (eventSource$: Observable, state$: Observable) => Observable + : (eventSource$: Observable, inputs$: Observable, state$: Observable) => Observable + +declare function useEventCallback, U = void>( + callback: EventCallback, +): ReturnedState +declare function useEventCallback, U = void>( + callback: EventCallback, + initialState: U, +): ReturnedState +declare function useEventCallback, U = void, I = void>( + callback: EventCallback, + initialState: U, + inputs: I, +): ReturnedState ``` #### Examples: @@ -223,3 +263,101 @@ function App() { ReactDOM.render(, document.querySelector('#app')) ``` + +**With state$:** + +[live demo](https://codesandbox.io/s/m95lz934x) + +```tsx +import React from "react"; +import ReactDOM from "react-dom"; +import { useEventCallback } from "rxjs-hooks"; +import { map, withLatestFrom } from "rxjs/operators"; + +function App() { + const [clickCallback, [description, x, y, prevDescription]] = useEventCallback( + (event$, state$) => + event$.pipe( + withLatestFrom(state$), + map(([event, state]) => [ + event.target.innerHTML, + event.clientX, + event.clientY, + state[0], + ]) + ), + ["nothing", 0, 0, "nothing"] + ); + + return ( +
+

+ click position: {x}, {y} +

+

"{description}" was clicked.

+

"{prevDescription}" was clicked previously.

+ + + +
+ ); +} + +const rootElement = document.getElementById("root"); +ReactDOM.render(, rootElement); +``` + +**A complex example: useEventCallback with both inputs$ and state$** + +[live demo](https://codesandbox.io/s/n1pn02jxym) + +```tsx +import React, { useState } from "react"; +import ReactDOM from "react-dom"; +import { useEventCallback } from "rxjs-hooks"; +import { map, withLatestFrom, combineLatest } from "rxjs/operators"; + +import "./styles.css"; + +function App() { + const [count, setCount] = useState(0); + const [clickCallback, [description, x, y, prevDesc]] = useEventCallback( + (event$, inputs$, state$) => + event$.pipe( + map(event => [event.target.innerHTML, event.clientX, event.clientY]), + combineLatest(inputs$), + withLatestFrom(state$), + map(([eventAndInput, state]) => { + const [[text, x, y], [count]] = eventAndInput; + const prevDescription = state[0]; + return [text, x + count, y + count, prevDescription]; + }) + ), + ["nothing", 0, 0, "nothing"], + [count] + ); + + return ( +
+

+ click position: {x}, {y} +

+

"{description}" was clicked.

+

"{prevDesc}" was clicked previously.

+ + + +
+

+ click buttons above, and then click this `+++` button, the position + numbers will grow. +

+ +
+
+ ); +} + +const rootElement = document.getElementById("root"); +ReactDOM.render(, rootElement); +``` \ No newline at end of file