createApp
createApp is how you bring your Refract components to life. It takes your root component and creates an application instance that can be mounted to the DOM, just like how a director brings a script to life on stage.
Think of it as the bridge between your reactive components and the browser - it handles the initial setup, mounting, and provides configuration options for your entire application.
Why createApp?
Every Refract application needs an entry point - a way to tell the browser "start here and render this component." createApp provides this entry point while also giving you control over how your application behaves in different environments.
Unlike directly manipulating the DOM, createApp sets up the reactive system, handles errors gracefully, and provides hooks for monitoring and debugging your application.
createApp
Creates a new Refract application instance that can be mounted to a DOM element.
Signature
const app = createApp(RootComponent, options?)
Parameters
RootComponentRefractComponentrequiredThe root component of your application
optionsAppOptionsOptional configuration for the application
Returns
A Refract application instance with mount/unmount methods
Example
import { createApp, createComponent } from "refract";
const App = createComponent(({ lens }) => {
return <h1>Hello, Refract!</h1>;
});
const app = createApp(App);
app.mount("#root");
Comparison with Traditional Approaches
Let's see how createApp compares to other ways of starting applications:
- React ReactDOM.render
- Refract createApp
- Live Result
import React from 'react';
import ReactDOM from 'react-dom/client';
const App = () => {
const [message, setMessage] = React.useState("Welcome to React!");
return (
<div>
<h1>{message}</h1>
<button onClick={() => setMessage("Hello, World!")}>
Change Message
</button>
</div>
);
};
// Create root and render
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
// No built-in error handling or configuration
Issues with React setup:
- Separate ReactDOM import required
- No built-in error boundaries
- Limited configuration options
- Manual error handling setup needed
import { createApp, createComponent } from "refract";
const App = createComponent(({ lens }) => {
const message = lens.useRefraction("Welcome to Refract!");
return (
<div>
<h1>{message.value}</h1>
<button onClick={() => message.set("Hello, World!")}>
Change Message
</button>
</div>
);
});
// Create app with built-in configuration
const app = createApp(App, {
onError: (error) => console.error('App error:', error),
devMode: true
});
// Mount with simple API
app.mount("#root");
Benefits of Refract createApp:
- Single import for everything
- Built-in error handling
- Rich configuration options
- Reactive state built-in
- Clean mounting API
Welcome to React!
Basic Usage
The most common way to create and mount a Refract application:
import { createApp, createComponent } from "refract";
const App = createComponent(({ lens }) => {
const message = lens.useRefraction("Welcome to Refract!");
return (
<div>
<h1>{message.value}</h1>
<button onClick={() => message.set("Hello, World!")}>
Change Message
</button>
</div>
);
});
// Create the application
const app = createApp(App);
// Mount to DOM element
app.mount("#root");
Application Options
Configure your application with various options:
const app = createApp(App, {
// Enable development mode features
devMode: process.env.NODE_ENV === 'development',
// Custom error handler
onError: (error, errorInfo) => {
console.error('Refract Error:', error, errorInfo);
// Send to error reporting service
},
// Performance monitoring
onPerformanceEntry: (entry) => {
console.log('Performance:', entry);
}
});
Application Methods
mount(selector)
Mounts the application to a DOM element:
- CSS Selector
- DOM Element
// Mount to element with ID
app.mount("#root");
// Mount to element with class
app.mount(".app-container");
// Mount to element by tag
app.mount("main");
// Mount to DOM element directly
const container = document.getElementById("root");
app.mount(container);
// Mount to dynamically created element
const div = document.createElement("div");
document.body.appendChild(div);
app.mount(div);
unmount()
Unmounts the application and cleans up resources:
// Mount the application
app.mount("#root");
// Later, unmount and cleanup
app.unmount();
// The DOM element is now empty and all
// reactive subscriptions are cleaned up
Multiple Applications
You can create multiple Refract applications on the same page:
import { createApp, createComponent } from "refract";
const HeaderApp = createComponent(({ lens }) => {
return <header>Header Content</header>;
});
const MainApp = createComponent(({ lens }) => {
return <main>Main Content</main>;
});
const FooterApp = createComponent(({ lens }) => {
return <footer>Footer Content</footer>;
});
// Create separate applications
const headerApp = createApp(HeaderApp);
const mainApp = createApp(MainApp);
const footerApp = createApp(FooterApp);
// Mount to different containers
headerApp.mount("#header");
mainApp.mount("#main");
footerApp.mount("#footer")
Error Handling
Handle application-level errors gracefully:
const app = createApp(App, {
onError: (error, errorInfo) => {
// Log error details
console.error('Application Error:', {
error: error.message,
stack: error.stack,
componentStack: errorInfo.componentStack,
timestamp: new Date().toISOString()
});
// Report to error tracking service
if (typeof window !== 'undefined' && window.Sentry) {
window.Sentry.captureException(error, {
contexts: {
react: {
componentStack: errorInfo.componentStack
}
}
});
}
// Show user-friendly error message
showErrorNotification('Something went wrong. Please refresh the page.');
}
});
Related APIs
- createComponent - Creating reactive components
- useRefraction - Managing reactive state
- useEffect - Side effects and lifecycle