createStoreWithComponent
Deprecated
createStoreWithComponent is deprecated and not recommended for new code. Use createStore instead — it covers the same reactive store needs with a simpler hook-based API. The content below is kept for reference and existing users.
🟢 Vue Approach - Advanced
This is an advanced feature of the Vue approach. Make sure you understand createStore first!
For React developers, this API may feel unusual. Consider using createState with React's built-in hooks instead.
Overview
createStoreWithComponent extends createStore with Vue-like lifecycle hooks. It creates a component that manages its own reactive state with lifecycle methods like onMounted, onUpdated, etc.
When to use:
- You want component-scoped state (not global)
- You need Vue's lifecycle hooks in React
- You're building reusable components with internal state
Signature:
function createStoreWithComponent<T>(config: { setup: () => T }): Component<T>;Quick Example
import { createStoreWithComponent, ref, onMounted, onUnmounted } from "reactivity-store";
const Timer = createStoreWithComponent({
setup: () => {
const seconds = ref(0);
let timer: any;
// Runs when component mounts
onMounted(() => {
console.log("Timer started");
timer = setInterval(() => seconds.value++, 1000);
});
// Runs before component unmounts
onUnmounted(() => {
console.log("Timer stopped");
clearInterval(timer);
});
return { seconds };
},
});
// Use as a component with render props
function App() {
return <Timer>{({ seconds }) => <div>Time elapsed: {seconds}s</div>}</Timer>;
}Available Lifecycle Hooks
All Vue lifecycle hooks are supported:
| Hook | When it runs | Use case |
|---|---|---|
onBeforeMount | Before component mounts | Setup before DOM |
onMounted | After component mounts | Start timers, fetch data |
onBeforeUpdate | Before component updates | Track update count |
onUpdated | After component updates | React to state changes |
onBeforeUnmount | Before component unmounts | Save data |
onUnmounted | After component unmounts | Cleanup timers, listeners |
Complete Example
Real-world timer with lifecycle hooks:
import { createStoreWithComponent, ref, onMounted, onBeforeUpdate, onUnmounted } from "reactivity-store";
const Clock = createStoreWithComponent({
setup: () => {
const time = ref(new Date().toLocaleTimeString());
const updateCount = ref(0);
let timerId: any;
onMounted(() => {
console.log("Clock started");
timerId = setInterval(() => {
time.value = new Date().toLocaleTimeString();
}, 1000);
});
onBeforeUpdate(() => {
updateCount.value++;
});
onUnmounted(() => {
console.log("Clock stopped");
clearInterval(timerId);
});
return { time, updateCount };
},
});
// Usage
function App() {
const [show, setShow] = React.useState(true);
return (
<div>
<button onClick={() => setShow(!show)}>{show ? "Hide" : "Show"} Clock</button>
{show && (
<Clock>
{({ time, updateCount }) => (
<div>
<p>Current time: {time}</p>
<p>Updates: {updateCount}</p>
</div>
)}
</Clock>
)}
</div>
);
}Comparison with createStore
// Component-scoped state with lifecycle
const Timer = createStoreWithComponent({
setup: () => {
const seconds = ref(0);
let timer;
onMounted(() => {
timer = setInterval(() => seconds.value++, 1000);
});
onUnmounted(() => clearInterval(timer));
return { seconds };
},
});
// Used as component
<Timer>{({ seconds }) => <div>{seconds}s</div>}</Timer>;// Global store, no lifecycle
const useTimer = createStore(() => {
const seconds = ref(0);
const start = () => {
const timer = setInterval(() => seconds.value++, 1000);
return () => clearInterval(timer);
};
return { seconds, start };
});
// Used as hook
function App() {
const { seconds, start } = useTimer();
React.useEffect(() => {
const cleanup = start();
return cleanup;
}, []);
return <div>{seconds}s</div>;
}Key Differences:
- createStoreWithComponent: Component-scoped, render props, Vue lifecycle
- createStore: Global store, hook-based, use React's useEffect
Important Notes
Render Props Pattern
createStoreWithComponent uses render props pattern, which may feel unusual in React:
<MyComponent>{(state) => <div>{state.value}</div>}</MyComponent>If you prefer hooks, use createStore instead.
State Management
Each instance of the component has its own state. If you need global state, use createStore.
// Two independent timers
<Timer>{({ seconds }) => <div>Timer 1: {seconds}</div>}</Timer>
<Timer>{({ seconds }) => <div>Timer 2: {seconds}</div>}</Timer>When to Use This API
✅ Use createStoreWithComponent when:
- Building reusable components with internal state
- You need Vue's lifecycle hooks
- State should be scoped to each component instance
- You're familiar with Vue Composition API
❌ Use createStore instead when:
- You need global/shared state
- You prefer React hooks over render props
- State should persist across component unmount/remount
- You want simpler API
Live Demo
Related APIs
- createStore - Global stores with Vue APIs
- createState - React approach with actions
- Reactive Hooks - Component-local reactive state
For React Developers
If the render props pattern feels awkward, consider using React's built-in hooks with createState:
import { createState } from "reactivity-store";
import { useEffect } from "react";
const useTimer = createState(() => ({ seconds: 0 }), {
withActions: (state) => ({
tick: () => state.seconds++,
}),
});
function Timer() {
const { seconds, tick } = useTimer();
useEffect(() => {
const timer = setInterval(tick, 1000);
return () => clearInterval(timer);
}, []);
return <div>{seconds}s</div>;
}This feels more natural in React! See createState for more.