rc-util: Common React Utilities
rc-util is a foundational utility library within the React ecosystem, specifically developed to provide common helper functions and components for other React libraries (often those under the `react-component` organization like Ant Design). It offers a suite of low-level utilities such as `createChainedFunction` for combining multiple event handlers, a `deprecated` logger for warning about API changes, and `Portal` for rendering children outside the DOM hierarchy. The current stable version is `5.44.4`. While a specific, detailed release cadence for `rc-util` is not directly specified in the available metadata, the project is actively maintained, receiving updates to address various React development challenges and support newer React versions, as evidenced by related package activity. Its key differentiator lies in its focused, unopinionated approach, providing essential building blocks without imposing architectural patterns, making it a reliable dependency for complex UI component libraries.
Common errors
-
ERROR in ./src/App.tsx Module not found: Error: Can't resolve 'rc-util'
cause The 'rc-util' package is not installed in the project's dependencies.fixInstall the package using your package manager: `npm install rc-util` or `yarn add rc-util`. -
TypeError: (0 , _rc_util_lib_createChainedFunction__WEBPACK_IMPORTED_MODULE_0__.default) is not a function
cause Attempting to use a named import or incorrect CommonJS `require` for a utility that is a default export from a specific deep path.fixAdjust your import statement to `import createChainedFunction from 'rc-util/lib/createChainedFunction';` for ESM, or `const createChainedFunction = require('rc-util/lib/createChainedFunction');` for CJS. -
ReferenceError: document is not defined
cause Trying to use browser-specific APIs (e.g., `document` or `HTMLElement` with `Portal`) in a Node.js server-side rendering (SSR) environment without proper safeguards.fixEnsure components or hooks that rely on browser APIs are executed only in client-side environments, or use appropriate SSR guards like `typeof window !== 'undefined'` to conditionally render or execute code.
Warnings
- gotcha The `rc-util` library primarily exposes its utilities as default exports from deep paths (e.g., `rc-util/lib/createChainedFunction`). This deviates from common modern practices of named exports directly from the root package, which can lead to 'Module not found' or 'is not a function' errors if users attempt `import { FunctionName } from 'rc-util';`.
- breaking rc-util declares `react` and `react-dom` as peer dependencies (`>=16.9.0`). As React major versions increment (e.g., React 18, React 19), there may be breaking changes in React's APIs that `rc-util`'s internal components or hooks rely on. While `rc-util` aims for compatibility, ensure your installed `rc-util` version is officially tested and compatible with your project's React version.
- gotcha The commit history provided pertains to `@rc-component/util` (version 1.x.x) rather than `rc-util` (version 5.x.x). While these packages likely share a lineage or common purpose, users should be aware that their specific `rc-util` version `5.44.4` might not directly reflect the features, fixes, or breaking changes detailed in the `@rc-component/util` commit logs. Always refer to `rc-util`'s specific documentation and changelog for the installed version.
Install
-
npm install rc-util -
yarn add rc-util -
pnpm add rc-util
Imports
- createChainedFunction
import { createChainedFunction } from 'rc-util';import createChainedFunction from 'rc-util/lib/createChainedFunction';
- deprecated
const deprecated = require('rc-util').deprecated;import deprecated from 'rc-util/lib/deprecated';
- Portal
import { Portal } from 'rc-util';import Portal from 'rc-util/lib/Portal';
Quickstart
import React, { useRef, useState } from 'react';
import { createRoot } from 'react-dom/client';
import createChainedFunction from 'rc-util/lib/createChainedFunction';
import Portal from 'rc-util/lib/Portal';
const App = () => {
const [log, setLog] = useState<string[]>([]);
const containerRef = useRef<HTMLDivElement>(null);
const handleClick1 = () => {
setLog(prev => [...prev, 'Function 1 called!']);
};
const handleClick2 = () => {
setLog(prev => [...prev, 'Function 2 called!']);
};
const chainedClickHandler = createChainedFunction(handleClick1, handleClick2);
const getPortalContainer = () => {
if (!containerRef.current) {
// Create container if it doesn't exist
const div = document.createElement('div');
div.id = 'portal-root';
document.body.appendChild(div);
containerRef.current = div;
}
return containerRef.current;
};
return (
<div>
<h1>rc-util Demo</h1>
<button onClick={chainedClickHandler}>
Click Me (Chained Functions)
</button>
<div style={{ marginTop: '20px', border: '1px solid #ccc', padding: '10px' }}>
<h2>Event Log:</h2>
{log.length === 0 ? <p>No events yet.</p> : log.map((msg, i) => <p key={i}>{msg}</p>)}
</div>
<div ref={containerRef} style={{ border: '1px dashed blue', padding: '10px', marginTop: '20px' }}>
Portal Mount Point (conceptually inside App, visually rendered here)
</div>
{/* Content rendered into the container obtained from getPortalContainer */}
<Portal getContainer={getPortalContainer}>
<div style={{ background: 'lightgreen', padding: '10px', border: '1px solid green' }}>
This content is rendered via Portal!
</div>
</Portal>
</div>
);
};
const rootElement = document.getElementById('root');
if (rootElement) {
createRoot(rootElement).render(<App />);
} else {
console.error("Root element with ID 'root' not found in the document.");
}