feat: add state hook
This commit is contained in:
parent
0f893d7341
commit
8454cb1154
3 changed files with 62 additions and 3 deletions
|
|
@ -2,6 +2,7 @@ import {
|
||||||
YarEffectTag,
|
YarEffectTag,
|
||||||
YarElement,
|
YarElement,
|
||||||
YarFiber,
|
YarFiber,
|
||||||
|
YarHook,
|
||||||
YarHTMLTagName,
|
YarHTMLTagName,
|
||||||
YarProps,
|
YarProps,
|
||||||
} from "./YarJs.interfaces";
|
} from "./YarJs.interfaces";
|
||||||
|
|
@ -10,6 +11,8 @@ let FIBER_TO_PROCESS: YarFiber | null | undefined = null;
|
||||||
let WIP_ROOT: YarFiber | null | undefined = null;
|
let WIP_ROOT: YarFiber | null | undefined = null;
|
||||||
let CURRENT_ROOT: YarFiber | null | undefined = null;
|
let CURRENT_ROOT: YarFiber | null | undefined = null;
|
||||||
let FIBERS_TO_DELETE: YarFiber[] = [];
|
let FIBERS_TO_DELETE: YarFiber[] = [];
|
||||||
|
let WIP_FIBER: YarFiber | null = null;
|
||||||
|
let HOOK_INDEX: number = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function converts Text into Dom Text Elements
|
* This function converts Text into Dom Text Elements
|
||||||
|
|
@ -52,7 +55,7 @@ function generateDomNode(fiber: YarFiber) {
|
||||||
const dom =
|
const dom =
|
||||||
fiber.type === "TEXT"
|
fiber.type === "TEXT"
|
||||||
? document.createTextNode("")
|
? document.createTextNode("")
|
||||||
: document.createElement(fiber.type);
|
: document.createElement(fiber.type as keyof React.JSX.IntrinsicElements);
|
||||||
|
|
||||||
updateDom(dom, {}, fiber.props);
|
updateDom(dom, {}, fiber.props);
|
||||||
|
|
||||||
|
|
@ -182,6 +185,10 @@ function updateFunctionComponent(fiber: YarFiber) {
|
||||||
|
|
||||||
if (!(fiber.type instanceof Function)) return;
|
if (!(fiber.type instanceof Function)) return;
|
||||||
|
|
||||||
|
WIP_FIBER = fiber;
|
||||||
|
HOOK_INDEX = 0;
|
||||||
|
WIP_FIBER.hooks = [];
|
||||||
|
|
||||||
const children = [fiber.type(fiber.props)];
|
const children = [fiber.type(fiber.props)];
|
||||||
reconcileChildren(fiber, children);
|
reconcileChildren(fiber, children);
|
||||||
}
|
}
|
||||||
|
|
@ -354,6 +361,44 @@ export function render(
|
||||||
FIBER_TO_PROCESS = WIP_ROOT;
|
FIBER_TO_PROCESS = WIP_ROOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useState<T>(initValue: T) {
|
||||||
|
// TODO:
|
||||||
|
|
||||||
|
const oldHook = WIP_FIBER?.alternate?.hooks?.at(HOOK_INDEX);
|
||||||
|
|
||||||
|
const hook: YarHook = {
|
||||||
|
state: oldHook ? oldHook.state : initValue,
|
||||||
|
queue: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const actions = oldHook?.queue ?? [];
|
||||||
|
|
||||||
|
actions.forEach((action) => {
|
||||||
|
hook.state = action(hook.state);
|
||||||
|
});
|
||||||
|
|
||||||
|
const setState = (action: Function) => {
|
||||||
|
hook.queue.push(action);
|
||||||
|
WIP_ROOT = {
|
||||||
|
type: "",
|
||||||
|
dom: CURRENT_ROOT!.dom,
|
||||||
|
parent: null,
|
||||||
|
child: null,
|
||||||
|
sibling: null,
|
||||||
|
alternate: CURRENT_ROOT,
|
||||||
|
effectTag: null,
|
||||||
|
props: CURRENT_ROOT!.props,
|
||||||
|
};
|
||||||
|
|
||||||
|
FIBER_TO_PROCESS = WIP_ROOT;
|
||||||
|
};
|
||||||
|
|
||||||
|
WIP_FIBER?.hooks?.push(hook);
|
||||||
|
HOOK_INDEX++;
|
||||||
|
|
||||||
|
return [hook.state, setState];
|
||||||
|
}
|
||||||
|
|
||||||
export function Fragment() {}
|
export function Fragment() {}
|
||||||
|
|
||||||
export default { render, createElement, Fragment };
|
export default { render, createElement, Fragment };
|
||||||
|
|
|
||||||
|
|
@ -26,4 +26,10 @@ export interface YarFiber extends YarElement {
|
||||||
sibling: null | YarFiber;
|
sibling: null | YarFiber;
|
||||||
alternate?: null | YarFiber;
|
alternate?: null | YarFiber;
|
||||||
effectTag: null | YarEffectTag;
|
effectTag: null | YarEffectTag;
|
||||||
|
hooks?: YarHook[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface YarHook {
|
||||||
|
state: any;
|
||||||
|
queue: any[];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
src/main.tsx
12
src/main.tsx
|
|
@ -1,10 +1,18 @@
|
||||||
import "./style.css";
|
import "./style.css";
|
||||||
import { render } from "./lib/YarJS";
|
import { render, useState } from "./lib/YarJS";
|
||||||
|
|
||||||
const root = document.querySelector<HTMLDivElement>("#app")!;
|
const root = document.querySelector<HTMLDivElement>("#app")!;
|
||||||
|
|
||||||
function App(props) {
|
function App(props) {
|
||||||
return <h1>Hi {props.name}</h1>;
|
const [state, setState] = useState(1);
|
||||||
|
|
||||||
|
const onClick = () => setState((old) => old + 1);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div onClick={onClick}>
|
||||||
|
<h1>Count {state}</h1>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const element = <App name="foo" />;
|
const element = <App name="foo" />;
|
||||||
|
|
|
||||||
Reference in a new issue