The createContext utility provides a simple way to create global or named shared state that components can subscribe to. It enables reactive state management with automatic subscriber notifications on value changes.
Import and create a context to manage shared state:
import createContext from './utils/context.js';
// Create a named context with initial value
const userContext = createContext('user', { name: 'Guest' });
// Subscribe to changes
userContext.subscribe((user) => {
console.log('User changed:', user);
});
// Update the context value
userContext.set({ name: 'John Doe' });
createContext(name, initialValue)Creates or retrieves a context with the specified name.
name: string (optional)The name of the context. Defaults to 'global'. Using the same name returns the same context instance.
initialValue: any (optional)The initial value for the context. Only set if the context doesn't already have a value.
ObjectAn object with the following methods:
get()Returns the current value of the context.
const currentValue = userContext.get();
set(value)Updates the context value and notifies all subscribers.
userContext.set({ name: 'Jane Doe', role: 'admin' });
subscribe(callback)Subscribes to context changes. The callback is immediately invoked with the current value, then called again whenever the value changes.
callback: FunctionFunction to call when the context value changes. Receives the new value as an argument.
FunctionAn unsubscribe function to remove the subscription.
const unsubscribe = userContext.subscribe((value) => {
console.log('New value:', value);
});
// Later, stop listening
unsubscribe();
unsubscribe(callback)Removes a subscriber callback from the context.
const handler = (value) => console.log(value);
userContext.subscribe(handler);
userContext.unsubscribe(handler);
import createContext from './utils/context.js';
const themeContext = createContext('theme', 'light');
// Components can subscribe to theme changes
themeContext.subscribe((theme) => {
document.body.className = theme;
});
// Toggle theme from anywhere
const toggleTheme = () => {
const current = themeContext.get();
themeContext.set(current === 'light' ? 'dark' : 'light');
};
import createContext from './utils/context.js';
const cartContext = createContext('cart', []);
// Add item from one component
const addToCart = (item) => {
const items = cartContext.get();
cartContext.set([...items, item]);
};
// Display cart in another component
cartContext.subscribe((items) => {
document.querySelector('.cart-count').textContent = items.length;
});
import createContext from './utils/context.js';
// Use default global context
const globalCtx = createContext();
globalCtx.set({ appReady: true });
// Named contexts are isolated
const userCtx = createContext('user');
const settingsCtx = createContext('settings');
// Same name returns the same context instance
const userCtx2 = createContext('user');
console.log(userCtx === userCtx2); // true
<div id="context-demo">
<p>Current count: <strong id="count-display">0</strong></p>
<button id="increment">Increment</button>
<button id="decrement">Decrement</button>
<button id="reset">Reset</button>
</div>
<script type="module">
import createContext from '../src/utils/context.js';
const counterContext = createContext('counter', 0);
// Subscribe to updates
counterContext.subscribe((count) => {
document.getElementById('count-display').textContent = count;
});
// Button handlers
document.getElementById('increment')
.addEventListener('click', () => {
counterContext.set(counterContext.get() + 1);
});
document.getElementById('decrement')
.addEventListener('click', () => {
counterContext.set(counterContext.get() - 1);
});
document.getElementById('reset')
.addEventListener('click', () => {
counterContext.set(0);
});
</script>
Current count: 0