-
Notifications
You must be signed in to change notification settings - Fork 129
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* JSX * more docs * doc edits * fix incremental update * don’t clear jsx pre-emptively * ReactDOM, too * more docs * jsx test * prerelease badge * move jsx higher
- Loading branch information
Showing
114 changed files
with
826 additions
and
248 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,7 @@ | ||
{ | ||
"resolve": { | ||
"extensions": [".js", ".jsx"] | ||
}, | ||
"env": { | ||
"browser": true | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
export function Card({title, children} = {}) { | ||
return ( | ||
<div className="card"> | ||
{title ? <h2>{title}</h2> : null} | ||
{children} | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
# JSX <a href="https://github.com/observablehq/framework/pull/1429" class="observablehq-version-badge" data-version="prerelease" title="Added in #1429"></a> | ||
|
||
[React](https://react.dev/) is a popular and powerful library for building interactive interfaces. React is typically written in [JSX](https://react.dev/learn/writing-markup-with-jsx), an extension of JavaScript that allows HTML-like markup. To use JSX and React, declare a JSX fenced code block (<code>```jsx</code>). For example, to define a `Greeting` component that accepts a `subject` prop: | ||
|
||
````md | ||
```jsx | ||
function Greeting({subject}) { | ||
return <div>Hello, <b>{subject}</b>!</div> | ||
} | ||
``` | ||
```` | ||
|
||
```jsx | ||
function Greeting({subject}) { | ||
return <div>Hello, <b>{subject}</b>!</div> | ||
} | ||
``` | ||
|
||
Then call the built-in display function to render content: | ||
|
||
```jsx echo | ||
display(<Greeting subject="JSX" />); | ||
``` | ||
|
||
You can combine React with Framework’s built-in [reactivity](./reactivity) by passing reactive values as props. Try changing the `name` below. | ||
|
||
```jsx echo | ||
display(<Greeting subject={name || "anonymous"} />); | ||
``` | ||
|
||
```js echo | ||
const name = view(Inputs.text({label: "Name", placeholder: "Anonymous"})); | ||
``` | ||
|
||
You can use hooks such as [`useState`](https://react.dev/reference/react/useState), [`useEffect`](https://react.dev/reference/react/useEffect), and [`useRef`](https://react.dev/reference/react/useRef). The `Counter` component below counts the number of times you click the button. | ||
|
||
```jsx echo | ||
function Counter() { | ||
const [count, setCount] = React.useState(0); | ||
return ( | ||
<button onClick={() => setCount(count + 1)}> | ||
You clicked {count} times | ||
</button> | ||
); | ||
} | ||
``` | ||
|
||
```jsx echo | ||
display(<Counter />); | ||
``` | ||
|
||
React is available by default as `React` in Markdown, but you can import it explicitly like so: | ||
|
||
```js run=false | ||
import * as React from "npm:react"; | ||
``` | ||
|
||
If you prefer, you can import specific symbols, such as hooks: | ||
|
||
```js run=false | ||
import {useState} from "npm:react"; | ||
``` | ||
|
||
React DOM is also available as `ReactDOM` in Markdown, or can be imported as: | ||
|
||
```js run=false | ||
import * as ReactDOM from "npm:react-dom"; | ||
``` | ||
|
||
You can define components in JSX modules. For example, if this were `components/Card.jsx`: | ||
|
||
```jsx run=false | ||
export function Card({title, children} = {}) { | ||
return ( | ||
<div className="card"> | ||
{title ? <h2>{title}</h2> : null} | ||
{children} | ||
</div> | ||
); | ||
} | ||
``` | ||
|
||
You could then import the `Card` component as: | ||
|
||
```js echo | ||
import {Card} from "./components/Card.js"; | ||
``` | ||
|
||
<div class="note"> | ||
|
||
Use the `.js` file extension when importing JSX (`.jsx`) modules; JSX is transpiled to JavaScript during build. | ||
|
||
</div> | ||
|
||
And, as before, you can render a card using the display function: | ||
|
||
```jsx echo | ||
display(<Card title="A test of cards">If you can read this, success!</Card>); | ||
``` | ||
|
||
Within a JSX fenced code block, the [display function](./javascript#explicit-display) 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. | ||
|
||
<div class="note"> | ||
|
||
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](https://github.com/observablehq/framework/issues/931) if you are interested in this feature. | ||
|
||
</div> | ||
|
||
## 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`](https://react.dev/reference/react-dom/client/createRoot): | ||
|
||
```js echo | ||
const node = document.createElement("SPAN"); | ||
const root = ReactDOM.createRoot(node); | ||
``` | ||
|
||
Then use a JSX code block to render the desired content into the root: | ||
|
||
```jsx echo | ||
root.render(<>Hello, <i>{name || "anonymous"}</i>!</>); | ||
``` | ||
|
||
Lastly, interpolate the root into the desired location with an inline expression: | ||
|
||
<div class="card"> | ||
<h2>Rendering into an inline expression</h2> | ||
${node} | ||
</div> | ||
|
||
```md run=false | ||
<div class="card"> | ||
<h2>Rendering into an inline expression</h2> | ||
${node} | ||
</div> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.