State Management
Refract provides a flexible and efficient state management system that works seamlessly with React components. This guide covers the core concepts and patterns for managing state in Refract applications.
Core Concepts
1. Local Component State
Use useRefraction hook for local component state:
import { createComponent, useRefraction } from 'refract';
const Counter = createComponent(({ lens }) => {
const count = lens.useRefraction(0);
return (
<div>
<p>Count: {count.value}</p>
<button onClick={() => count.value++}>Increment</button>
</div>
);
});
2. Global State
Create global state using createRefraction:
// store.js
import { createRefraction } from 'refract';
export const store = createRefraction({
user: null,
theme: 'light',
preferences: {}
});
// In your component
const { user, theme } = store.value;
State Updates
Basic Updates
// Direct mutation (simplest)
count.value += 1;
// Using setter function (functional update)
count.set(prev => prev + 1);
Batching Updates
import { batch } from 'refract';
// Multiple state updates in a single render
batch(() => {
user.value = { ...user.value, name: 'John' };
theme.value = 'dark';
});
State Composition
Derived State
const fullName = useDerived(
() => `${firstName.value} ${lastName.value}`,
[firstName, lastName]
);
State Selectors
const userName = useRefraction(
() => store.value.user?.name,
[store]
);
Best Practices
- Colocate State: Keep state as close to where it's used as possible
- Lift State Up: When multiple components need the same state
- Use Context for Global State: For app-wide state that many components need
- Memoize Expensive Computations: Use
useMemofor derived state - Batch Updates: Group related state updates together
Advanced Patterns
State Machines
const [state, send] = useMachine({
initial: 'idle',
states: {
idle: {
on: { FETCH: 'loading' }
},
loading: {
on: {
SUCCESS: 'success',
ERROR: 'error'
}
},
// ...
}
});
Middleware
const app = createApp(App, {
middleware: [
logger,
devTools,
persistState('app-state')
]
});