@nozbe/with-observables

    1.4.0 • Public • Published

    withObservables

    MIT License CI Status npm

    A higher-order component for connecting RxJS Observables to React components.

    Example

    (Taken from WatermelonDB)

    const Post = ({ post, comments }) => (
      <article>
        <h1>{post.name}</h1>
        <p>{post.body}</p>
        <h2>Comments</h2>
        {comments.map(comment =>
          <EnhancedComment key={comment.id} comment={comment} />
        )}
      </article>
    )
    
    const enhance = withObservables(['post'], ({ post }) => ({
      post: post.observe(),
      comments: post.comments.observe()
    }))
    
    const EnhancedPost = enhance(Post)

    ➡️ Learn more: Connecting WatermelonDB to Components

    Installation

    yarn add @nozbe/with-observables

    And then to use:

    import withObservables from '@nozbe/with-observables'

    Usage

    withObservables(triggerProps, getObservables)
    
    // Injects new props to a component with values from the passed Observables
    //
    // Every time one of the `triggerProps` changes, `getObservables()` is called
    // and the returned Observables are subscribed to.
    //
    // Every time one of the Observables emits a new value, the matching inner prop is updated.
    //
    // You can return multiple Observables in the function. You can also return arbitrary objects that have
    // an `observe()` function that returns an Observable.
    //
    // The inner component will not render until all supplied Observables return their first values.
    // If `triggerProps` change, renders will also be paused until the new Observables emit first values.
    //
    // If you only want to subscribe to Observables once (the Observables don't depend on outer props),
    // pass `null` to `triggerProps`.
    //
    // Errors are re-thrown in render(). Use React Error Boundary to catch them.
    //
    // Example use:
    //   withObservables(['task'], ({ task }) => ({
    //     task: task,
    //     comments: task.comments.observe()
    //   }))

    Typescript

    The TypeScript bindings expose a helper type, ObservableifyProps<Props, ObservableKeys, ObservableConvertibleKeys> which can make it easier to wrap components without duplicating interfaces:

    interface Props {
      post: Post;
      author: Author;
      someOtherProp: boolean;
      anotherProp: number;
    }
    
    const PostRenderer: React.FC<Props> = (props) => ( ... );
    
    type InputProps = ObservableifyProps<Props, "author", "post">
    const enhance = withObservables(["post", "author"], ({ post }: InputProps) => ({
      post,
      author: author.observe()
    });
    
    export default enhance(PostRenderer);

    Or you can let getObservables define your props for you:

    import withObservables, {ExtractedObservables} from "@nozbe/with-observables"
    
    const getObservables = ({ post }: { post: Post }}) => ({
      post,
      author: author.observe()
    });
    
    interface Props extends ExtractedObservables<ReturnType<typeof getObservables>> {
      someOtherProp: boolean;
      anotherProp: number;
    }
    
    const PostRenderer: React.FC<Props> = (props) => (
      <>{props.author.id}</>
    );
    
    export default withObservables(["post"], getObservables)(PostRenderer);

    Author and license

    withObservables was created by @Nozbe for WatermelonDB.

    withObservables is available under the MIT license. See the LICENSE file for more info.

    Install

    npm i @nozbe/with-observables

    DownloadsWeekly Downloads

    5,191

    Version

    1.4.0

    License

    MIT

    Unpacked Size

    50.8 kB

    Total Files

    11

    Last publish

    Collaborators

    • nozbe-user
    • radex
    • tkapelak
    • kokusgr
    • rozpierog
    • jsamelak