Skip to content

Commit

Permalink
refactor: simplify jsx-runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
hi-ogawa committed Oct 19, 2023
1 parent 5407df2 commit 36d0296
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 49 deletions.
55 changes: 9 additions & 46 deletions packages/tiny-react/src/helper/jsx-runtime.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import {
NODE_TYPE_CUSTOM,
NODE_TYPE_TAG,
type NodeKey,
type VNode,
} from "../virtual-dom";
import type { ComponentChildren, ComponentType } from "./common";
import { Fragment, createElement } from "./hyperscript";
import { createVNode } from "../virtual-dom";
import { Fragment } from "./hyperscript";
import type { JSX } from "./jsx-namespace";

// jsx-runtime convention for transpilers
Expand All @@ -14,41 +8,10 @@ import type { JSX } from "./jsx-namespace";
// https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md#detailed-design
// https://github.com/preactjs/preact/blob/08b07ccea62bfdb44b983bfe69ae73eb5e4f43c7/jsx-runtime/src/index.js

export function jsx(
tag: ComponentType,
props: { children?: ComponentChildren },
key?: NodeKey
): VNode {
// TODO
// as the main motivation of jsx-runtime, we can similary delay props normalization until render time.
// we can simply keep "raw" props (except key) on VTag and VCustom
// then ref/children normalization is done when reconciled to BTag and BCustom.
const { children, ...propsNoChildren } = props;
return createElement(tag, { key, ...propsNoChildren }, props.children);
}

export function jsx2(
tag: ComponentType,
props: { children?: ComponentChildren },
key?: NodeKey
): VNode {
if (typeof tag === "function") {
return {
type: NODE_TYPE_CUSTOM,
key,
props,
render: tag,
};
} else if (typeof tag === "string") {
// TODO: VTagLazy
return {
type: NODE_TYPE_TAG,
name: tag,
key,
props,
} as any;
}
return tag satisfies never;
}

export { jsx as jsxs, jsx as jsxDEV, Fragment, type JSX };
export {
createVNode as jsx,
createVNode as jsxs,
createVNode as jsxDEV,
Fragment,
type JSX,
};
5 changes: 2 additions & 3 deletions packages/tiny-react/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { tinyassert } from "@hiogawa/utils";
import { describe, expect, it, vi } from "vitest";
import { createRoot, memo } from "./compat";
import { Fragment, createElement, h } from "./helper/hyperscript";
import { jsx2 } from "./helper/jsx-runtime";
import {
useCallback,
useEffect,
Expand All @@ -13,7 +12,7 @@ import {
} from "./hooks";
import { render, updateCustomNode } from "./reconciler";
import { sleepFrame } from "./test-utils";
import { EMPTY_NODE, getBNodeSlot } from "./virtual-dom";
import { EMPTY_NODE, createVNode, getBNodeSlot } from "./virtual-dom";

describe(render, () => {
it("basic", () => {
Expand Down Expand Up @@ -1582,7 +1581,7 @@ describe("custom-children", () => {
const root = createRoot(parent);
const vnode = h.div(
{},
jsx2(Custom, { children: "hello" }, "key1"),
createVNode(Custom, { children: "hello" }, "key1"),
createElement(Custom, { key: "key2" }, "hello")
);
root.render(vnode);
Expand Down

0 comments on commit 36d0296

Please sign in to comment.