{"id":11847,"library":"react-rx","title":"React-Rx: Hooks and Utilities for RxJS Integration","description":"React-Rx is a library designed to seamlessly integrate RxJS Observables into React applications, providing both React Hooks and higher-order component utilities. It excels at handling Observables that emit values synchronously without incurring an immediate re-render on mount, optimizing performance. The library, currently at stable version 4.2.2, maintains a consistent release cadence with frequent updates for bug fixes and dependency upgrades, often related to React Compiler advancements. It offers full TypeScript support and differentiates itself by providing two distinct yet powerful patterns: a set of `useObservable` hooks for functional components and a `reactiveComponent` utility for a more declarative, component-based approach. Users are encouraged to choose one style rather than mixing them within the same component, as they represent different programming paradigms. It requires `rxjs` version 7 or higher and `react` version 18.3 or 19.0.0-0, ensuring compatibility with modern React ecosystems.","status":"active","version":"4.2.2","language":"javascript","source_language":"en","source_url":"https://github.com/sanity-io/react-rx","tags":["javascript","action","behavior","concurrent","es6","events","external","hooks","observables","typescript"],"install":[{"cmd":"npm install react-rx","lang":"bash","label":"npm"},{"cmd":"yarn add react-rx","lang":"bash","label":"yarn"},{"cmd":"pnpm add react-rx","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core reactive programming library, required for creating and manipulating observables.","package":"rxjs","optional":false},{"reason":"Core UI library, required for all React-based applications.","package":"react","optional":false}],"imports":[{"note":"The primary hook for consuming observables in functional components. Requires ESM imports since v3.","wrong":"const useObservable = require('react-rx').useObservable;","symbol":"useObservable","correct":"import { useObservable } from 'react-rx';"},{"note":"A utility hook for creating an Observable from React callbacks. Used for event streams.","wrong":"import useObservableCallback from 'react-rx/useObservableCallback';","symbol":"useObservableCallback","correct":"import { useObservableCallback } from 'react-rx';"},{"note":"A higher-order component (HOC) utility for creating reactive components. Not intended to be mixed with `useObservable` hooks in the same component.","wrong":"import reactiveComponent from 'react-rx/reactiveComponent';","symbol":"reactiveComponent","correct":"import { reactiveComponent } from 'react-rx';"},{"note":"Observable is part of RxJS, not `react-rx`. Always import directly from 'rxjs'.","wrong":"import { Observable } from 'react-rx';","symbol":"Observable","correct":"import { Observable } from 'rxjs';"}],"quickstart":{"code":"import React, { useMemo } from 'react';\nimport { useObservable } from 'react-rx';\nimport { interval, map, take } from 'rxjs';\n\ninterface CounterProps {\n  startAt: number;\n  intervalMs: number;\n}\n\nfunction ObservableCounter({ startAt, intervalMs }: CounterProps) {\n  const counterObservable = useMemo(\n    () => interval(intervalMs).pipe(\n      map(i => startAt + i),\n      take(10) // Stop after 10 emissions to prevent infinite updates\n    ),\n    [startAt, intervalMs]\n  );\n\n  const count = useObservable(counterObservable, startAt); // Initial value\n\n  return (\n    <div>\n      <h2>Observable Counter</h2>\n      <p>Current count: {count}</p>\n      <p>Will count from {startAt} every {intervalMs}ms for 10 times.</p>\n    </div>\n  );\n}\n\nexport default function App() {\n  return (\n    <div>\n      <h1>React-Rx Demonstration</h1>\n      <ObservableCounter startAt={0} intervalMs={1000} />\n      <ObservableCounter startAt={100} intervalMs={500} />\n    </div>\n  );\n}\n","lang":"typescript","description":"This quickstart demonstrates how to use the `useObservable` hook to subscribe to an RxJS `interval` observable and display its emitted values in a React functional component. It showcases two independent counters."},"warnings":[{"fix":"Ensure your project is configured for ES Modules (e.g., `\"type\": \"module\"` in `package.json`, `moduleResolution: \"NodeNext\"` in `tsconfig.json`) and use `import` syntax for `react-rx` and `rxjs`.","message":"Older versions of `react-rx` (prior to v3) might have supported CommonJS (`require()`) imports. Since v3, the library is primarily designed for ES Modules, requiring `import` statements. Attempting to `require()` this package in a pure ESM context or misconfigured bundler can lead to runtime errors.","severity":"breaking","affected_versions":"<3.0.0"},{"fix":"Decide on either a hook-based approach with `useObservable` for functional components or a higher-order component approach with `reactiveComponent`, and adhere to that style within a given component.","message":"Mixing `useObservable` hooks and `reactiveComponent` within the same React component is not recommended due to their fundamentally different programming styles and underlying implementations. Choose one paradigm for consistency and clarity.","severity":"gotcha","affected_versions":">=4.0.0"},{"fix":"Ensure your project's `react` and `rxjs` versions match the peer dependency requirements: `rxjs: \"^7\"` and `react: \"^18.3 || >=19.0.0-0\"`. Use `npm install` or `yarn install` to resolve peer dependency warnings.","message":"Incorrect peer dependency versions for `react` or `rxjs` can lead to runtime issues or unexpected behavior. `react-rx` relies heavily on specific versions of these libraries.","severity":"gotcha","affected_versions":">=4.0.0"},{"fix":"Be mindful of observables that emit synchronously (e.g., `of()`, `new BehaviorSubject()`). If you always want an initial placeholder, consider delaying the observable's first emission or ensuring it is truly asynchronous, or explicitly handle the initial synchronous emission.","message":"When `useObservable` is provided with an `initialValue` and the observable emits synchronously at subscription time, the synchronously emitted value will be used, ignoring the `initialValue`. This can be unexpected if not aware of RxJS's synchronous emission capabilities.","severity":"gotcha","affected_versions":">=4.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Install `rxjs` explicitly: `npm install rxjs@^7` or `yarn add rxjs@^7`.","cause":"The `rxjs` peer dependency is missing or an incompatible version is installed.","error":"Error: Can't resolve 'rxjs' in 'your-project/node_modules/react-rx'"},{"fix":"Verify that your project and bundler (e.g., Webpack, Rollup) are configured to handle ES Modules (`import` statements). Ensure your `package.json` has `\"type\": \"module\"` if it's an ESM project, and use `import { useObservable } from 'react-rx';`.","cause":"This usually indicates a CommonJS (`require`) attempt to load an ES Module (`react-rx`) or a bundler misconfiguration in an older project.","error":"TypeError: (0, _react_rx.useObservable) is not a function"},{"fix":"Convert your component to a functional component or refactor the logic to be used within a custom hook, or consider using `reactiveComponent` for class-like reactive patterns if a class component is strictly required.","cause":"`useObservable` is a React Hook and adheres to React's Rules of Hooks.","error":"React Hook 'useObservable' cannot be called inside a class component. React Hooks can only be called from a function component or custom Hook."}],"ecosystem":"npm"}