React
The React filter enables you to build React and Preact components using Ruby syntax.
Function Components (Recommended)
The modern approach uses function components with hooks. Simply inherit from React or Preact:
class Counter < React
def initialize
@count = 0
end
def render
%x{
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
}
end
end
This generates a function component with useState hooks:
@count = 0becomesconst [count, setCount] = React.useState(0)@@propaccessesprops.prop
Class Components
For components that need lifecycle methods, inherit from React::Component:
class Timer < React::Component
def initialize
@seconds = 0
end
def componentDidMount
@interval = setInterval(1000) { @seconds += 1 }
end
def componentWillUnmount
clearInterval(@interval)
end
def render
%x{ <p>Seconds: {this.state.seconds}</p> }
end
end
JSX Syntax
Elements are created using JSX syntax with %x{...}:
class Example < React
def render
%x{
<div className="container">
<h1>Hello</h1>
<p>Welcome to React</p>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
}
end
end
JSX Features
- Standard HTML elements:
<div>,<p>,<span>, etc. - React components (capitalized):
<MyComponent /> - Custom elements:
<my-widget /> - Fragments:
<>...</> - Expressions:
{expression} - Spread attributes:
{...props}
Attribute Names
JSX uses camelCase attribute names:
| JSX | HTML |
|---|---|
className |
class |
htmlFor |
for |
onClick |
onclick |
tabIndex |
tabindex |
Variable Mappings
| Ruby | JavaScript | Notes |
|---|---|---|
@x |
useState hook or this.state.x |
Instance variables become state |
@@x |
props.x |
Class variables become props |
$x |
this.refs.x |
Global variables become refs |
~x |
this.refs.x |
Tilde also accesses refs |
~(expr) |
document.querySelector(expr) |
DOM queries |
Preact Support
The same filter supports Preact. Use Preact instead of React:
class Counter < Preact
# Same syntax as React
end
Differences from React:
- Uses
Preact.hinstead ofReact.createElement - Uses
onInputinstead ofonChangefor form inputs - Uses
classinstead ofclassName
Phlex Integration
The React filter can be combined with the Phlex filter for a “write once, target both” approach. Write components using Phlex’s Ruby DSL and output either Phlex JS or React JS:
# Same Phlex code, different outputs
Ruby2JS.convert(code, filters: [:phlex]) # → Phlex JS (template literals)
Ruby2JS.convert(code, filters: [:phlex, :react]) # → React JS (createElement)
See the Building UI Components guide for the full picture, or Phlex filter documentation for API details.