Build a Counter App
Build a Counter App with Refract
Welcome to your first hands-on tutorial with Refract! In this guide, we'll build a simple counter application while learning fundamental concepts like refractions (reactive state) and component creation. This is the perfect starting point before tackling more advanced topics like optics or global state.
What You'll Learn
- Creating reactive state with refractions
- Building components with
createComponent- Handling user interactions
- Basic state updates
Prerequisites
Before we begin, make sure you've:
- Set up a Refract project Quick Start
- Understand basic JavaScript
New to Refract?
If terms like "refractions" sound unfamiliar, check out our Core Concepts overview first.
Initialize Your App
First, let's set up the foundation in your main app file:
import { createApp } from '@refract-framework/core';
const app = createApp();
This creates a new Refract application instance. The createApp function is your gateway to all Refract features - we'll explore more advanced uses in the API Reference.
Create a Counter Component
Now, let's build our counter component using createComponent:
import { createComponent, useRefraction } from '@refract-framework/core';
const Counter = createComponent(() => {
const [count, setCount] = useRefraction(0); // Initialize with 0
return {
view: () => (
<div>
<p>Current count: {count.value}</p>
<button onClick={() => setCount(count.value + 1)}>
Increment
</button>
</div>
)
};
});
Live Demo
// This is the actual code used in the demo
const Counter = createComponent(() => {
const [count, setCount] = useRefraction(0);
return {
view: () => (
<div>
<p>Count: {count.value}</p>
<button onClick={() => setCount(count.value + 1)}>
Increment
</button>
</div>
)
};
});
Let's break this down:
-
useRefraction(0)creates a reactive state (refraction) initialized to0 -
count.valueaccesses the current value -
setCount()updates the value and triggers re-renders
Here’s a simple timeline of what happens when you click the button:
Button Click
↓
count.value++
↓
Refract detects change
↓
UI auto re-renders
No manual DOM updates needed — Refract handles the reactivity for you.
Unlike React's useState, refractions are part of Refract's reactive system that works seamlessly with optics and effects..
Add Decrement Functionality
Let's enhance our counter with decrement logic:
const Counter = createComponent(() => {
const [count, setCount] = useRefraction(0);
const increment = () => setCount(count.value + 1);
const decrement = () => setCount(count.value - 1);
return {
view: () => (
<div>
<p>Current count: {count.value}</p>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</div>
)
};
});
Register and Mount the Component
Finally, let's add our component to the app:
app.registerComponent('counter', Counter);
// In your HTML:
// <div id="app"></div>
app.mount('#app');