rcrx
v0.0.4
Published
Rcrx is a lightweight library that provides Rx.js utilities for React applications.
Maintainers
Readme
Rcrx
Lightweight RxJS hooks for React. 简洁的 React + RxJS Hook 工具库。
- English | 中文
Overview
Rcrx provides a minimal set of hooks to seamlessly use RxJS Observables within React components:
- useObservable — read the latest value from an Observable as React state
- useSubscribe — subscribe to an Observable and map each emission using your function
Designed to be tiny, typed, and easy to adopt.
Features
- Minimal API, zero configuration
- Automatic subscription management (unsubscribe on unmount)
- TypeScript support with generics
- Works with any RxJS Observable
- Keeps subscription stable when the mapping function changes (via ref)
Installation
Using your favorite package manager:
# pnpm
pnpm add rcrx rxjs
# npm
npm install rcrx rxjs
# yarn
yarn add rcrx rxjsPeer requirements:
- react >= 16.8.0 (hooks)
- rxjs (any 7+ recommended)
Quick Start
useObservable
import { useObservable } from "rcrx";
import { Observable } from "rxjs";
const counter$ = new Observable<number>((subscriber) => {
let n = 0;
const id = setInterval(() => subscriber.next(n++), 1000);
return () => clearInterval(id);
});
function Counter() {
const n = useObservable(counter$);
return <div>{n}</div>;
}useSubscribe
import { useSubscribe } from "rcrx";
import { Observable } from "rxjs";
import { useState } from "react";
const counter$ = new Observable<number>((subscriber) => {
let n = 0;
const id = setInterval(() => subscriber.next(n++), 1000);
return () => clearInterval(id);
});
function Counter() {
const [n, setN] = useState(0);
useSubscribe(counter$, (v) => setN(v));
return <div>{n}</div>;
}API
useObservable(observable: Observable): T | undefined
- Subscribes to the provided observable when the component mounts and returns the latest emitted value.
- Re-subscribes if the observable instance changes.
- Returns undefined until the first value is emitted.
useSubscribe<TValue, TReturnValue>(
observable: Observable, fn: (value: TValue) => TReturnValue, defaultReturnValue?: TReturnValue ): TReturnValue | undefined
- Subscribes to the observable and applies fn to each emission; the hook returns the latest mapped result.
- Keeps the same subscription even if fn changes (fn is stored in a ref).
- Re-subscribes if the observable instance changes.
- Returns defaultReturnValue initially (or undefined if omitted).
Notes:
- For side-effects only, ignore the return value and use fn to update component state.
- For derived state, return a mapped value from fn and read the hook's return value.
Advanced Usage
Switching Observables
function Dynamic({ source }: { source: Observable<number> }) {
const value = useObservable(source);
return <div>{value}</div>;
}When the source prop changes to a different Observable instance, the hook will unsubscribe from the previous one and subscribe to the new one.
Mapping Without Re-subscribing
function Mapped({ source }: { source: Observable<number> }) {
const doubled = useSubscribe(source, (v) => v * 2, 0);
return <div>{doubled}</div>;
}Changing the mapping function identity won’t cause a re-subscription; only the Observable instance identity matters.
TypeScript
- Fully typed generics for both hooks
- No additional TS configuration required
Development
- Build:
pnpm build(outputs todist/via tsup) - Test:
pnpm testorpnpm test:watch(Vitest)
License
ISC
中文说明
Rcrx 提供一组极简的 React + RxJS Hook,帮助你在 React 组件中无缝使用 RxJS Observable:
- useObservable —— 将 Observable 的最新值作为组件状态读取
- useSubscribe —— 订阅 Observable,并用你的函数映射每次推送
特性
- API 极简、开箱即用
- 自动管理订阅(组件卸载自动取消订阅)
- 完整的 TypeScript 支持
- 适配任意 RxJS Observable
- 当映射函数变更时保持订阅稳定(通过 ref)
安装
# pnpm
pnpm add rcrx rxjs
# npm
npm install rcrx rxjs
# yarn
yarn add rcrx rxjs对等依赖与推荐:
- react >= 16.8.0(支持 Hook)
- rxjs(建议 7+)
快速上手
useObservable
import { useObservable } from "rcrx";
import { Observable } from "rxjs";
const counter$ = new Observable<number>((subscriber) => {
let n = 0;
const id = setInterval(() => subscriber.next(n++), 1000);
return () => clearInterval(id);
});
function Counter() {
const n = useObservable(counter$);
return <div>{n}</div>;
}useSubscribe
import { useSubscribe } from "rcrx";
import { Observable } from "rxjs";
import { useState } from "react";
const counter$ = new Observable<number>((subscriber) => {
let n = 0;
const id = setInterval(() => subscriber.next(n++), 1000);
return () => clearInterval(id);
});
function Counter() {
const [n, setN] = useState(0);
useSubscribe(counter$, (v) => setN(v));
return <div>{n}</div>;
}API 说明
useObservable(observable: Observable): T | undefined
- 组件挂载时订阅 Observable,并返回其最新推送值;当 Observable 实例变化时自动重新订阅。
- 在首次推送之前返回 undefined。
useSubscribe<TValue, TReturnValue>(
observable: Observable, fn: (value: TValue) => TReturnValue, defaultReturnValue?: TReturnValue ): TReturnValue | undefined
- 订阅 Observable,并对每次推送应用 fn;Hook 返回最近一次映射的结果。
- fn 变更不会触发重新订阅(内部通过 ref 保存最新 fn)。
- 当 Observable 实例变化时会重新订阅。
- 初始返回 defaultReturnValue(未传入则为 undefined)。
提示:
- 仅用于副作用时,可忽略返回值,直接在 fn 中 setState。
- 需要派生状态时,可在 fn 中返回映射值,并通过 Hook 的返回值读取。
进阶用法
切换 Observable
function Dynamic({ source }: { source: Observable<number> }) {
const value = useObservable(source);
return <div>{value}</div>;
}当 source 属性切换为新的 Observable 实例时,Hook 会自动取消之前的订阅,并订阅到新的实例。
映射但不重新订阅
function Mapped({ source }: { source: Observable<number> }) {
const doubled = useSubscribe(source, (v) => v * 2, 0);
return <div>{doubled}</div>;
}映射函数的引用发生变化不会触发重新订阅;只有 Observable 实例变化时才会。
本地开发
- 构建:
pnpm build(使用 tsup 输出到dist/) - 测试:
pnpm test或pnpm test:watch(Vitest)
许可证
MIT
