FastContext
FastContext is a performance-optimized context implementation that uses refs and subscriptions to avoid unnecessary re-renders. Unlike traditional React Context, FastContext allows you to subscribe to specific parts of the store using selectors, ensuring components only re-render when the selected data changes.
Key Features
- Selector-based subscriptions: Only re-render when selected data changes
- Ref-based store: Access store values without causing re-renders using
useStoreRef - Fine-grained updates: Update specific parts of the store without affecting unrelated components
- Equality checks: Customizable equality functions for selector comparisons
API
createFastContext<T>(defaultValue?, watch?)
Creates a new FastContext instance.
Parameters:
defaultValue(optional): Default value for the storewatch(optional): Iftrue, the provider will watch for prop changes and update the store
Returns:
Provider: Context provider componentuseContext: Hook that returns[selectedValue, setter]useContextValue: Hook that returns just the selected valueuseStoreRef: Hook that returns the store ref (doesn't cause re-renders)Context: The underlying React context (useful for ContextBridge)
Examples
Basic Usage
import { createFastContext } from 'react-native-molecules/fast-context';
type Store = {
count: number;
name: string;
};
const { Provider, useContext, useContextValue } = createFastContext<Store>({
count: 0,
name: 'Initial',
});
// In your component tree
export const App = () => {
return (
<Provider value={{ count: 0, name: 'John' }}>
<Counter />
<NameDisplay />
</Provider>
);
};
// Component that needs both value and setter
const Counter = () => {
const [count, setStore] = useContext(state => state.count);
return (
<View>
<Text>Count: {count}</Text>
<Button
onPress={() => setStore(prev => ({ count: prev.count + 1 }))}
>
Increment
</Button>
</View>
);
};
// Component that only needs the value
const NameDisplay = () => {
const name = useContextValue(state => state.name);
return <Text>Name: {name}</Text>;
};
Using useStoreRef (No Re-renders)
const { Provider, useStoreRef } = createFastContext<Store>();
const NonRenderingComponent = () => {
const storeRef = useStoreRef();
const handleClick = () => {
// Access current value without causing re-render
const currentCount = storeRef.current.get().count;
console.log('Current count:', currentCount);
};
return <Button onPress={handleClick}>Log Count</Button>;
};
With Custom Equality Check
const { Provider, useContext } = createFastContext<Store>();
const CustomEqualityComponent = () => {
// Only re-render if the user object reference changes
const [user, setStore] = useContext(
state => state.user,
(a, b) => a.id === b.id && a.name === b.name
);
return <Text>{user.name}</Text>;
};
Watch Mode
When watch is enabled, the provider will automatically update the store when the value prop changes:
const { Provider } = createFastContext<Store>(null, true);
export const App = () => {
const [storeValue, setStoreValue] = useState({ count: 0, name: 'John' });
return (
<Provider value={storeValue}>
{/* Store will update when storeValue changes */}
<ChildComponent />
</Provider>
);
};
Integration with ContextBridge
FastContext can be used with ContextBridge to bridge contexts across render boundaries:
const { Provider, Context } = createFastContext<Store>();
// Register the context with a bridge
registerContextToBridge(Context);
When to Use
- Large stores: When you have a large context store and want to avoid unnecessary re-renders
- Performance-critical components: Components that need to access context but shouldn't re-render frequently
- Selective subscriptions: When different components need different parts of the same store
- Complex state management: When you need fine-grained control over when components update
Benefits Over Traditional Context
- Reduced re-renders: Components only re-render when their selected data changes
- Selector-based: Fine-grained control over what triggers updates
- Ref access: Access store values without causing re-renders
- Better performance: Especially beneficial for large applications with complex state