JSX
React is a popular and powerful library for building interactive interfaces. React is typically written in JSX, an extension of JavaScript that allows HTML-like markup. To use JSX and React, declare a JSX fenced code block (```jsx
). You can alternatively use a TSX fenced code block (```tsx
) if using JSX with TypeScript.
For example, to define a Greeting
component that accepts a subject
prop:
```jsx
function Greeting({subject}) {
return <div>Hello, <b>{subject}</b>!</div>
}
```
Then call the built-in display function to render content:
```jsx
display(<Greeting subject="JSX" />);
```
You can combine React with Framework’s built-in reactivity by passing reactive values as props. Try changing the name
below.
display(<Greeting subject={name || "anonymous"} />);
const name = view(Inputs.text({label: "Name", placeholder: "Anonymous"}));
You can use hooks such as useState
, useEffect
, and useRef
. The Counter
component below counts the number of times you click the button.
function Counter() {
const [count, setCount] = React.useState(0);
return (
<button onClick={() => setCount(count + 1)}>
You clicked {count} times
</button>
);
}
display(<Counter />);
React is available by default as React
in Markdown, but you can import it explicitly like so:
import * as React from "npm:react";
If you prefer, you can import specific symbols, such as hooks:
import {useState} from "npm:react";
React DOM is also available as ReactDOM
in Markdown, or can be imported as:
import * as ReactDOM from "npm:react-dom";
You can define components in JSX modules. For example, if this were components/Card.jsx
:
export function Card({title, children} = {}) {
return (
<div className="card">
{title ? <h2>{title}</h2> : null}
{children}
</div>
);
}
You could then import the Card
component as:
import {Card} from "./components/Card.js";
Use the .js
file extension when importing JSX (.jsx
) modules; JSX is transpiled to JavaScript during build.
And, as before, you can render a card using the display function:
display(<Card title="A test of cards">If you can read this, success!</Card>);
Within a JSX fenced code block, the display function behaves a bit differently from a JavaScript fenced code block or inline expression: it replaces the previously-displayed content, if any. In addition, JSX fenced code blocks do not support implicit display; content can only be displayed explicitly.
In the future we intend to support other JSX-compatible frameworks, such as Preact. We are also working on server-side rendering with client-side hydration; please upvote #931 if you are interested in this feature.
Inline expressions
JSX is not currently supported in inline expression ${…}
; only JavaScript is allowed in inline expressions. However, you can declare a detached root using createRoot
:
const node = document.createElement("SPAN");
const root = ReactDOM.createRoot(node);
Then use a JSX code block to render the desired content into the root:
root.render(<>Hello, <i>{name || "anonymous"}</i>!</>);
Lastly, interpolate the root into the desired location with an inline expression:
Rendering into an inline expression
<div class="card">
<h2>Rendering into an inline expression</h2>
${node}
</div>