Skip to content

Feature request: add support for error handling and tap option #116

@kristianmandrup

Description

@kristianmandrup

See useRx and useRxTap here

import { useEffect, useState } from "react";
import { Observable, Subscription } from "rxjs";
import { tap } from 'rxjs/operators';

/**
 * Reactive Hook that returns a tuple of resolved value and error.
 * @param { Observable<T> } observable$
 * @param { T } defaultValue
 */
export function useRx<T>(
  observable$: Observable<T>,
  defaultValue: T | (() => T)
): [T, any?] {
  const [x, setX] = useState(defaultValue);
  const [error, setError] = useState();

  let subscription: Subscription;
  useEffect(() => {
    if (!subscription) {
      subscription = observable$.subscribe(setX, setError);
    }
    return () => subscription.unsubscribe();
  }, [observable$]);

  return [x, error];
}

/**
 * Reactive Hook that triggers callbacks on observable updates.
 * @param { Observable<T> } observable$
 * @param { T } defaultValue
 */
export function useRxTap<T>(
  observable$: Observable<T>,
  next?: (x: T) => void, 
  error?: (e: any) => void, 
  complete?: () => void
): void {
  let subscription: Subscription;
  useEffect(() => {
    if (!subscription) {
      subscription = observable$.pipe(tap(next, error, complete)).subscribe();
    }
    return () => subscription.unsubscribe();
  }, [observable$]);
}

Example usage:

export default function History({ last5$ }) {
    ...
    const [items, error] = useRx(last5$, []);
    return (
        <ul>
            {items.map(item => (
                <li key={item.id}>{item.id}</li>
             ))}
       </ul>
   );
}

Also related to #2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions