useConstant
Create a stable reference that's initialized once and never changes. Like useRef but with lazy initialization for expensive computations.
Live Demo
See how useConstant only initializes once, while regular objects are recreated on every render.
📊 Render Statistics
Total Renders:1
useConstant Calls:1
Regular Object Calls:1
✅ useConstant Value
Computation Time: 20ms
Result: 21081849486.44
Created: 8:24:08 PM
✨ Initialized once, never changes
❌ Regular Object
Created: 8:24:08 PM
⚠️ Recreated on every render
📝 Event Log
No events yet
💡 Notice:
- useConstant initializer only runs once (on first render)
- Regular object is recreated on every render
- Perfect for expensive computations or stable references
- Similar to useRef but with lazy initialization
Code Examples
Basic Usage
import { useConstant } from "@uiblock/hooks";
export default function Example() {
// This expensive computation only runs once
const config = useConstant(() => {
console.log('Initializing config...');
return {
apiUrl: process.env.API_URL,
timeout: 5000,
retries: 3
};
});
return <div>API URL: {config.apiUrl}</div>;
}Expensive Computation
import { useConstant } from "@uiblock/hooks";
export default function DataProcessor() {
const processedData = useConstant(() => {
// This expensive operation only runs once
const largeDataset = fetchLargeDataset();
return largeDataset.map(item => ({
...item,
computed: expensiveComputation(item)
}));
});
return <div>{processedData.length} items processed</div>;
}Stable Event Handlers
import { useConstant } from "@uiblock/hooks";
export default function EventExample() {
const eventBus = useConstant(() => {
// Create event bus once
return new EventEmitter();
});
const logger = useConstant(() => {
// Create logger instance once
return new Logger({ level: 'debug' });
});
return <div>Event bus and logger initialized</div>;
}vs useRef
import { useConstant } from "@uiblock/hooks";
import { useRef } from "react";
export default function Comparison() {
// useRef - must initialize with value
const ref = useRef(expensiveComputation()); // ❌ Runs every render!
// useRef with lazy init pattern
const ref2 = useRef<ReturnType<typeof expensiveComputation>>();
if (!ref2.current) {
ref2.current = expensiveComputation(); // ✅ But verbose
}
// useConstant - clean and lazy
const value = useConstant(() => expensiveComputation()); // ✅ Perfect!
return <div>Value: {value}</div>;
}How It Works
Here's the implementation:
import { useRef } from 'react'
export function useConstant<T>(fn: () => T): T {
const ref = useRef<{ value: T }>()
if (!ref.current) {
ref.current = { value: fn() }
}
return ref.current.value
}Key Features:
- Lazy initialization - function only runs once
- Returns the same reference on every render
- Cleaner than useRef for initialized values
- Perfect for expensive computations
API Reference
Parameters
fn: () => TInitializer function that returns the constant value. Only called once on first render.
Returns
T - The constant value that never changes across renders
💡 Use Cases
- Expensive computations that should only run once
- Creating stable class instances (EventEmitter, Logger, etc.)
- Configuration objects that never change
- Stable references for third-party libraries
- Avoiding unnecessary re-computations
- Cleaner alternative to useRef for initialized values