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,
|
||||
YarElement,
|
||||
YarFiber,
|
||||
YarHook,
|
||||
YarHTMLTagName,
|
||||
YarProps,
|
||||
} from "./YarJs.interfaces";
|
||||
|
|
@ -10,6 +11,8 @@ let FIBER_TO_PROCESS: YarFiber | null | undefined = null;
|
|||
let WIP_ROOT: YarFiber | null | undefined = null;
|
||||
let CURRENT_ROOT: YarFiber | null | undefined = null;
|
||||
let FIBERS_TO_DELETE: YarFiber[] = [];
|
||||
let WIP_FIBER: YarFiber | null = null;
|
||||
let HOOK_INDEX: number = 0;
|
||||
|
||||
/**
|
||||
* This function converts Text into Dom Text Elements
|
||||
|
|
@ -52,7 +55,7 @@ function generateDomNode(fiber: YarFiber) {
|
|||
const dom =
|
||||
fiber.type === "TEXT"
|
||||
? document.createTextNode("")
|
||||
: document.createElement(fiber.type);
|
||||
: document.createElement(fiber.type as keyof React.JSX.IntrinsicElements);
|
||||
|
||||
updateDom(dom, {}, fiber.props);
|
||||
|
||||
|
|
@ -182,6 +185,10 @@ function updateFunctionComponent(fiber: YarFiber) {
|
|||
|
||||
if (!(fiber.type instanceof Function)) return;
|
||||
|
||||
WIP_FIBER = fiber;
|
||||
HOOK_INDEX = 0;
|
||||
WIP_FIBER.hooks = [];
|
||||
|
||||
const children = [fiber.type(fiber.props)];
|
||||
reconcileChildren(fiber, children);
|
||||
}
|
||||
|
|
@ -354,6 +361,44 @@ export function render(
|
|||
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 default { render, createElement, Fragment };
|
||||
|
|
|
|||
|
|
@ -26,4 +26,10 @@ export interface YarFiber extends YarElement {
|
|||
sibling: null | YarFiber;
|
||||
alternate?: null | YarFiber;
|
||||
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 { render } from "./lib/YarJS";
|
||||
import { render, useState } from "./lib/YarJS";
|
||||
|
||||
const root = document.querySelector<HTMLDivElement>("#app")!;
|
||||
|
||||
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" />;
|
||||
|
|
|
|||
Reference in a new issue