framework
framework copied to clipboard
react/jsx should work with view
```jsx echo
const a = view(<input type="range"></input>);
```
${a}
I’m not sure this is right. The virtual DOM and the real DOM aren’t the same; this is confusing concepts. (Maybe it would make sense if JSX produced real DOM, but it doesn’t.)
It's also confusing that it wouldn't work (if you don't mind about the implementation and only see jsx as a different syntax to write HTML).
The error message looks like a type error — view expects a DOM node, and receives a different type of object: maybe we should protect it in some way (by throwing a helpful error?).
The aim of course is to make a jsx block fully part of a page dataflow (not only a leaf).
obsolete comment
Here's my current solution:
```js echo
const upstreamValue = Mutable();
const updateUpstreamValue = (value) => upstreamValue.value = value;
```
${upstreamValue}
```jsx echo
function Counter() {
const [count, setCount] = React.useState(0);
updateUpstreamValue(count); // ↑ inform the page
return (
<button onClick={() => setCount(count + 1)}>
You clicked {count} times
</button>
);
}
```
```jsx echo
display(<Counter />);
```
It works but I don't really like it: boilerplate, the use of a Mutable, and the fact that it tracks the state in two different layers.
I don’t see a reason to duplicate state in this example. Also, you wouldn’t want a Counter component that hard-codes a reference to updateUpstreamValue; a component implies reusability, but hard-coding a reference to a global prevents it.
Instead, lift the state up to the page:
```js echo
const count = Mutable();
const setCount = (value) => count.value = value;
```
${count}
```jsx echo
function Counter({count, setCount}) {
return (
<button onClick={() => setCount(count + 1)}>
You clicked {count} times
</button>
);
}
```
```jsx echo
display(<Counter count={count} setCount={setCount} />);
```
Related https://vanillajsx.com/