
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
react-ref-store
Advanced tools
npm install react-ref-store
# or
pnpm add react-ref-store
# or
yarn add react-ref-store
createRefsStore<T>()A factory function that creates Context, Provider, and Hook all at once with type safety.
// Define your refs type
type TabRefs = {
'tab-button': HTMLButtonElement;
'tab-panel': HTMLDivElement;
};
const TabRefsStore = createRefsStore<TabRefs>();
// Returns
{
Provider, // Context Provider component
useStore, // Hook to get the store
}
useRefsStore<T>()Creates a store that manages refs as a Map data structure with type safety. (Can be used standalone without Context)
type SearchRefs = {
'search-field': HTMLDivElement;
'search-input': HTMLInputElement;
};
function MyComponent() {
const refsStore = useRefsStore<SearchRefs>();
// Use Map API: refsStore.get(), refsStore.has(), etc.
}
useRegisterRef<T, K>()A hook that registers a DOM element's ref to the Store with type safety.
const ref = useRegisterRef(refsStore, 'unique-key');
return <div ref={ref}>...</div>;
// 1. Define your refs type
type TabRefs = {
'tab-button': HTMLButtonElement;
'tab-panel': HTMLDivElement;
};
// 2. Create Store
const TabRefsStore = createRefsStore<TabRefs>();
// 3. Wrap with Provider
export function TabGroup({ children }) {
return (
<TabRefsStore.Provider>
{children}
</TabRefsStore.Provider>
);
}
// 4. Register in child components
function Tab({ id, children }) {
const store = TabRefsStore.useStore();
const ref = useRegisterRef(store, id); // TypeScript infers correct element type
return <button ref={ref}>{children}</button>;
}
// 5. Use the Store
function TabIndicator({ activeTabId }) {
const store = TabRefsStore.useStore();
const activeTab = store.get(activeTabId); // Returns HTMLButtonElement | undefined
if (!activeTab) return null;
const rect = activeTab.getBoundingClientRect();
// Calculate position and render indicator...
}
// You can inject an external store into the Provider
function CustomTabGroup({ children, externalStore }) {
return (
<TabRefsStore.Provider refsStore={externalStore}>
{children}
</TabRefsStore.Provider>
);
}
When using standalone without Context:
type FormRefs = {
'submit-btn': HTMLButtonElement;
'email-input': HTMLInputElement;
};
function StandaloneComponent() {
const refsStore = useRefsStore<FormRefs>();
// Use Map API with type safety
const buttonRef = refsStore.get('submit-btn'); // HTMLButtonElement | undefined
const hasInput = refsStore.has('email-input'); // boolean
return <ChildComponent refsStore={refsStore} />;
}
// Different element types for different keys
type ComplexRefs = {
'header': HTMLHeaderElement;
'nav': HTMLNavElement;
'main-content': HTMLMainElement;
'footer': HTMLFooterElement;
'submit-button': HTMLButtonElement;
'search-input': HTMLInputElement;
};
const LayoutStore = createRefsStore<ComplexRefs>();
function Header() {
const store = LayoutStore.useStore();
const ref = useRegisterRef(store, 'header'); // RefObject<HTMLHeaderElement>
return <header ref={ref}>Header</header>;
}
function SearchBar() {
const store = LayoutStore.useStore();
const ref = useRegisterRef(store, 'search-input'); // RefObject<HTMLInputElement>
return <input ref={ref} type="search" />;
}
interface RefsMap<T extends Record<string, HTMLElement>> {
register<K extends keyof T>(key: K, element: T[K] | undefined): void; // Register element
unregister<K extends keyof T>(key: K): void; // Unregister element
get<K extends keyof T>(key: K): T[K] | undefined; // Get element
has<K extends keyof T>(key: K): boolean; // Check if element exists
clear(): void; // Remove all elements
}
interface ProviderProps<T extends Record<string, HTMLElement>> {
children: ReactNode;
refsStore?: RefsMap<T>; // Optional external store injection
}
interface UseRegisterRefOptions {
isDefer?: boolean; // Defer registration using requestAnimationFrame (default: true)
isEnabled?: boolean; // Enable/disable registration (default: true)
}
createRefsStore<T>()useRefsStore<T>()useStore()refsStore prop to ProvideruseRegisterRef returns the correct ref type for each keyMIT
Contributions are always welcome! Please read the contribution guidelines first.
If you find a bug, please create an issue here.
FAQs
A lightweight React library for managing refs in a centralized store
We found that react-ref-store demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.