Coming from React¶
The component/state model is React's. The language and element syntax change.
| React/JSX | PyReact Forge |
|---|---|
function App(props) { ... } |
@component on def App(...) |
<Button label="Save" /> |
Button(label="Save") or h(Button, label="Save") |
<div className="card"> |
html.div(..., class_="card") |
onClick={() => ...} |
on_click=lambda: ... |
useState, useEffect |
use_state, use_effect |
items.map(item => <Row key={item.id}/>) |
A Python list comprehension with key= |
createContext / provider |
create_context / context.provide(..., value=...) |
Preserve React's rules¶
Call hooks at the top level of the component or a custom hook. Keep render pure. Treat props and state as snapshots; create a new list/dict/object for updates. Use stable keys for list items. Clean up subscriptions in effects.
Python components must be synchronous. For async data, use a stable resource
with Suspense rather than async def App. Browser event handlers may be async.
Understand the interop boundary¶
Python component props preserve Python objects. Registered JavaScript components
receive native JS arrays/objects. Browser events, DOM nodes and refs can be JS
proxies: read str(event.target.value) when you want an ordinary Python string.
React's scheduler is real, but a long synchronous Python function still occupies the main thread until it returns. There is no Python React Compiler, complete ESLint-equivalent hook analysis or state-preserving Fast Refresh in this alpha.
The optional router is intentionally small; it does not claim React Router loader, nested-route or framework-mode compatibility.
Next: state, async data, or the compatibility matrix.