This guide explores all the powerful features that make Reflex a robust state management solution.
The foundation of Reflex is the reactive value - a container that notifies subscribers when its contents change.
const name = reflex({ initialValue: 'John' });
name.subscribe(value => console.log(`Name changed to: ${value}`));
name.setValue('Jane'); // Logs: Name changed to: Jane
Track changes in nested objects and arrays automatically:
const user = deepReflex({
initialValue: {
profile: {
name: 'John',
settings: { theme: 'dark' }
}
}
});
// Direct property modification - automatically tracks nested changes
user.value.profile.settings.theme = 'light'; // Triggers update
// For multiple changes, use batch to trigger only one update
user.batch(value => {
value.profile.name = 'Jane';
value.profile.settings.theme = 'dark';
});
Create values that automatically update based on other reactive values:
const firstName = reflex({ initialValue: 'John' });
const lastName = reflex({ initialValue: 'Doe' });
const fullName = computed(
[firstName, lastName],
([first, last]) => `${first} ${last}`
);
fullName.subscribe(name => console.log(name)); // Logs: John Doe
firstName.setValue('Jane'); // Logs: Jane Doe
Transform and combine reactive values:
const numbers = reflex({ initialValue: 1 });
const doubled = numbers.map(n => n * 2);
const numbers = reflex({ initialValue: 0 });
const positiveOnly = numbers.filter(n => n > 0);
const combined = combine([value1, value2, value3]);
Transform values as they flow through your reactive system:
const counter = reflex({
initialValue: 0,
middleware: [
// Ensure value is non-negative
value => Math.max(0, value),
// Log all changes
value => {
console.log(`Counter changed to: ${value}`);
return value;
}
]
});
Built-in protection against common issues:
const safeValue = reflex({
initialValue: 0,
onError: (error) => {
console.error('Error in reactive value:', error);
return 0; // Fallback value
}
});
Enable detailed logging for debugging:
const debugValue = reflex({
initialValue: 0,
debug: true // Enables detailed logging
});
Reflex automatically manages subscriptions to prevent memory leaks:
const value = reflex({ initialValue: 0 });
const unsubscribe = value.subscribe(console.log);
// Later, when you're done:
unsubscribe();
// or
value.cleanup(); // Removes all subscriptions
function useReflex<T>(reflexValue: Reflex<T>): T {
const [value, setValue] = useState(reflexValue.getValue());
useEffect(() => {
return reflexValue.subscribe(setValue);
}, [reflexValue]);
return value;
}
// In setup()
const value = ref(reflexValue.getValue());
onMounted(() => {
const unsubscribe = reflexValue.subscribe(newValue => {
value.value = newValue;
});
onUnmounted(unsubscribe);
});
@Component({
template: '{{ value$ | async }}'
})
export class MyComponent {
value$ = from(reflexValue);
}
- Cleanup Subscriptions: Always store and call unsubscribe functions when done.
- Use Computed Values: Instead of manual synchronization, use computed values.
- Enable Debug Mode during development to catch issues early.
- Use Middleware for cross-cutting concerns like validation or logging.
- Check out the Advanced Usage Guide for more complex scenarios
- See Best Practices for optimization tips
- Review the API Reference for detailed method documentation
- Explore our deep dive guides for specific features: