📝 docs(code-reader): React 钩子原型的函数参数一律收成 fold,函数体展开成子块
This commit is contained in:
1 parent
67e8a77f5d
commit
a139341132
5 files changed
+3582
-3087
No files matched your search
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 271 KiB After Width: | Height: | Size: 271 KiB |
+7
-3
@@ -53,6 +53,7 @@ const K = {
|
||||
component: { label: "React 组件", color: "#61dafb", icon: "atom" },
|
||||
handler: { label: "事件处理函数", color: "#dcdcaa", icon: "mouse-pointer-click" },
|
||||
render: { label: "渲染输出", color: "#89d185", icon: "layout-template" },
|
||||
return: { label: "返回", color: "#89d185", icon: "corner-down-left" },
|
||||
};
|
||||
|
||||
const MONO = "Menlo";
|
||||
@@ -842,8 +843,11 @@ const changed = (name) => [seg(name, C.variable), seg(" 变化时", C.keyword)];
|
||||
const ON_MOUNT = [seg("仅挂载时", C.keyword)];
|
||||
const NO_DEPS = [seg("没写,", C.desc), seg("每次渲染后", C.keyword)];
|
||||
|
||||
/** 函数参数收成的小框:朝右的折叠箭头,写「函数 (参数) · N 句」,没参数时不写括号;同调用链原型的闭包小框。 */
|
||||
function fnBox(params, count) {
|
||||
/**
|
||||
* 函数参数收成的小框:折叠箭头,写「函数 (参数) · N 句」,没参数时不写括号;同调用链原型的闭包小框。
|
||||
* 默认收起(箭头朝右),`open` 时展开(箭头朝下),函数体是卡片下面的子块。
|
||||
*/
|
||||
function fnBox(params, count, open) {
|
||||
const segs = [seg("函数", C.desc)]
|
||||
.concat(params ? [seg(" (", C.fg)].concat(params, [seg(")", C.fg)]) : [])
|
||||
.concat([seg(" · " + count + " 句", C.desc)]);
|
||||
@@ -859,7 +863,7 @@ function fnBox(params, count) {
|
||||
fill: C.input,
|
||||
stroke: C.borderStrong,
|
||||
});
|
||||
icon(pill, "chevron-right", C.desc, 13);
|
||||
icon(pill, open ? "chevron-down" : "chevron-right", C.desc, 13);
|
||||
text(pill, segs, { mono: true, size: 12.5, lh: 18 });
|
||||
},
|
||||
};
|
||||
|
||||
+45
-6
@@ -5,6 +5,7 @@
|
||||
// 画板一照抄 luffy-agent-platform 的 frontend/client-nextjs/src/app/desktop/login/page.tsx 第 1–37 行,
|
||||
// 画板二是手写的三行,讲没标类型、函数形式的默认值、只取当前值三种写法;
|
||||
// 画板三把其它常用钩子照同一个思路画:卡片讲这个变量(或这条语句)是什么,钩子退到「来自」一行,样例是手写的搜索面板。
|
||||
// 钩子收的函数参数一律只画小框「函数 · N 句」,函数体是卡片下面的子块(画板三的 visible 画成展开的样子)。
|
||||
// 窗口、对齐、别的卡片的画法在同目录 react-shared.js,接在它后面跑:`cat react-shared.js react-state.js | op design - --script`。
|
||||
|
||||
// ─── 样例源码 ────────────────────────────────────────────────────────────────
|
||||
@@ -243,8 +244,32 @@ const line = (label, value, o) => (ctx) => prop(ctx, label, value, o);
|
||||
const fromRow = (hook, tip, linked) => (ctx) => prop(ctx, "来自", (frame) =>
|
||||
text(frame, [seg(hook, C.fn, linked ? { u: true } : {})], { mono: true, name: `${hook}(悬停:${tip})` }));
|
||||
|
||||
/** 收起的函数体一行:小框「函数 (参数) · N 句」,同 [fnBox]。 */
|
||||
const fnRow = (label, params, count) => (ctx) => prop(ctx, label, (frame) => fnBox(params, count).draw(frame));
|
||||
/** 钩子收的函数参数一行:只画小框「函数 (参数) · N 句」,同 [fnBox],函数体是卡片的子块;`open` 时小框是展开的样子。 */
|
||||
const fnRow = (label, params, count, open) => (ctx) => prop(ctx, label, (frame) => fnBox(params, count, open).draw(frame));
|
||||
|
||||
/**
|
||||
* 一张卡片连同它展开的子块:卡片下面隔 8px 是下一层,左边一条竖线标出这一层(同编辑器、预览对齐里的子块竖线),
|
||||
* `children` 在竖线右边,宽度少 20px。
|
||||
*/
|
||||
function withChildren(drawCard, children) {
|
||||
return (parent, w) => {
|
||||
const block = col(parent, "Block", { gap: 8 });
|
||||
drawCard(block, w);
|
||||
const level = row(block, "Level", { gap: 8, align: "start" });
|
||||
const guide = col(level, "Guide", { width: 12, height: "fill_container", align: "center" });
|
||||
I(guide, { type: "rectangle", name: "Line", width: 1, height: "fill_container", fill: solid(C.guide) });
|
||||
const list = col(level, "Blocks", { gap: 8 });
|
||||
children(list, w - 20);
|
||||
};
|
||||
}
|
||||
|
||||
/** 一行译文的「返回」卡片,照现有返回卡片:返回图标、绿色描边,译文按词性着色。 */
|
||||
function returnCard(src) {
|
||||
return (parent, w) => {
|
||||
const ctx = card(parent, K.return, w);
|
||||
text(ctx.content, cx(src), { mono: true, maxW: ctx.w });
|
||||
};
|
||||
}
|
||||
|
||||
/** 带「N 个」和展开表的一行(参数)。 */
|
||||
const tableRow = (label, cols, rows) => (ctx) => {
|
||||
@@ -258,11 +283,13 @@ const changedAll = (names) => names.flatMap((name, i) => (i > 0 ? [seg("、", C.
|
||||
/**
|
||||
* 一处 useState:名称照源码写出解构(展开是「第几项 | 名称 | 说明 | 操作」,当前值查谁用了它,修改函数查谁改了它)/
|
||||
* 来自 / 状态类型(没写时「未标注」)/ 默认值。`names` 是解构出的名字,`calls` 是各项在样例里出现几次。
|
||||
* 默认值是函数时 `fold` 写「closed」:函数体是卡片的子块,收起。
|
||||
*/
|
||||
function stateCard(s) {
|
||||
return valueCard({
|
||||
kind: STATE,
|
||||
lang: VAR,
|
||||
fold: s.fold,
|
||||
title: s.names[0],
|
||||
name: { kind: "array", items: s.names.map((name, i) => ({ name, color: i === 0 ? C.variable : C.fn, what: ITEMS[i].what, tip: ITEMS[i].tip, calls: s.calls[i] })) },
|
||||
bubble: s.bubble,
|
||||
@@ -369,7 +396,17 @@ windowOf("Prototype / React 状态 · 其他写法", WIN_W + BOARD_GAP, VARIANTS
|
||||
{
|
||||
from: 2,
|
||||
to: 2,
|
||||
draw: stateCard({ names: ["items", "setItems"], calls: [0, 0], type: [link("Item", C.type), seg("[]", C.fg)], initial: [seg("首次渲染时调用 ", C.fg)].concat(cx("loadItems()")) }),
|
||||
draw: stateCard({
|
||||
names: ["items", "setItems"],
|
||||
calls: [0, 0],
|
||||
fold: "closed",
|
||||
type: [link("Item", C.type), seg("[]", C.fg)],
|
||||
initial: (frame) => {
|
||||
const holder = row(frame, "Initial", { gap: 6, height: 20, width: "fit_content" });
|
||||
text(holder, "首次渲染时调用", { mono: true });
|
||||
fnBox(null, 1).draw(holder);
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
from: 3,
|
||||
@@ -552,19 +589,21 @@ const INPUT_REF = valueCard({
|
||||
],
|
||||
});
|
||||
|
||||
const VISIBLE = valueCard({
|
||||
// useMemo 的计算函数展开着:函数体只有一个表达式,算 1 句,子块是一张返回卡片
|
||||
const VISIBLE = withChildren(valueCard({
|
||||
kind: MEMO_VALUE,
|
||||
lang: VAR,
|
||||
fold: "open",
|
||||
title: "visible",
|
||||
name: "visible",
|
||||
calls: 1,
|
||||
tip: "谁用了",
|
||||
rows: [
|
||||
fromRow("useMemo", BUILTIN_TIP),
|
||||
line("计算", cx("results.filter((r) => r.hidden 不成立)")),
|
||||
fnRow("计算", null, 1, true),
|
||||
line("重算时机", changedAll(["results"])),
|
||||
],
|
||||
});
|
||||
}), returnCard("返回 results.filter((r) => r.hidden 不成立)"));
|
||||
|
||||
const SUBMIT = valueCard({
|
||||
kind: MEMO_FN,
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user