import { jsx, jsxs, Fragment } from 'solid-jsx/jsx-runtime';

/*@jsxRuntime automatic @jsxImportSource solid-jsx*/
const toc = [{
  "depth": 1,
  "value": "渲染",
  "children": [{
    "depth": 2,
    "value": "JSX 编译",
    "children": []
  }, {
    "depth": 2,
    "value": "Attributes 和 Props",
    "children": []
  }, {
    "depth": 2,
    "value": "入口",
    "children": []
  }, {
    "depth": 2,
    "value": "组件",
    "children": []
  }, {
    "depth": 2,
    "value": "Props",
    "children": []
  }, {
    "depth": 2,
    "value": "Children",
    "children": []
  }]
}];
function _createMdxContent(props) {
  const _components = Object.assign({
    h1: "h1",
    a: "a",
    p: "p",
    h2: "h2",
    ul: "ul",
    li: "li",
    code: "code",
    pre: "pre",
    span: "span",
    blockquote: "blockquote",
    strong: "strong",
    em: "em"
  }, props.components);
  return jsxs(Fragment, {
    children: [jsxs(_components.h1, {
      id: "渲染",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#渲染",
        children: "#"
      }), "渲染"]
    }), "\n", jsx(_components.p, {
      children: "Solid 支持 JSX、标签模板字面量 和 Solid HyperScript 变体这 3 种模板形式。其中 JSX 是主流，这是因为 JSX 是一门优秀的编译型 DSL。它有着清晰的语法，支持 TypeScript，可与 Babel 配合使用，并支持其他工具，如代码语法高亮和 Prettier。使用一种基本上免费为你提供所有功能的工具是相当务实的。JSX 作为一个编译的解决方案，它提供了很好的开发体验。当你可以使用一门如此广受支持且支持自定义语法的 DSL 时，有什么可纠结的呢？"
    }), "\n", jsxs(_components.h2, {
      id: "jsx-编译",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#jsx-编译",
        children: "#"
      }), "JSX 编译"]
    }), "\n", jsx(_components.p, {
      children: "渲染涉及到将 JSX 模板预编译为优化的原生 js 代码。JSX 代码会被构造成："
    }), "\n", jsxs(_components.ul, {
      children: ["\n", jsx(_components.li, {
        children: "在每个实例都会被克隆的模板 DOM 元素"
      }), "\n", jsx(_components.li, {
        children: "仅使用 firstChild 和 nextSibling 的一系列引用声明"
      }), "\n", jsx(_components.li, {
        children: "更新已创建元素的细粒度计算"
      }), "\n"]
    }), "\n", jsx(_components.p, {
      children: "与使用 document.createElement 一个一个地创建每个元素相比，这种方法的性能更高，生成的代码更少。"
    }), "\n", jsxs(_components.h2, {
      id: "attributes-和-props",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#attributes-和-props",
        children: "#"
      }), "Attributes 和 Props"]
    }), "\n", jsx(_components.p, {
      children: "Solid 尝试尽可能地与 HTML 的 attribute 保持一致，包括不区分属性的大小写。"
    }), "\n", jsxs(_components.p, {
      children: ["原生元素 JSX 上的大多数 attribute 都被设置为 DOM attribute。静态值会直接内置到克隆模板中。也有例外，诸如 ", jsx(_components.code, {
        children: "class"
      }), "、", jsx(_components.code, {
        children: "style"
      }), "、", jsx(_components.code, {
        children: "value"
      }), "、", jsx(_components.code, {
        children: "innerHTML"
      }), "之类会提供了额外的功能。"]
    }), "\n", jsxs(_components.p, {
      children: ["但是，自定义元素（内置的原生元素除外）在动态时默视为认为 property。这是为了处理更复杂的数据类型。为了遵循习惯，Solid 直接将蛇形命名（", jsx(_components.code, {
        children: "some-attr"
      }), "）转化为驼峰命名（", jsx(_components.code, {
        children: "someAttr"
      }), "）。"]
    }), "\n", jsxs(_components.p, {
      children: ["但是，也可以使用命名空间指令直接控制该行为。你可以使用 ", jsx(_components.code, {
        children: "attr:"
      }), " 指定 attribute 或者使用 ", jsx(_components.code, {
        children: "prop:"
      }), " 指定 property"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: ["<my-element ", jsx(_components.span, {
          className: "hljs-attr",
          children: "prop"
        }), ":", jsx(_components.span, {
          className: "hljs-title class_",
          children: "UniqACC"
        }), "={state.", jsx(_components.span, {
          className: "hljs-property",
          children: "value"
        }), "} ", jsx(_components.span, {
          className: "hljs-attr",
          children: "attr"
        }), ":title={state.", jsx(_components.span, {
          className: "hljs-property",
          children: "title"
        }), "} />\n"]
      })
    }), "\n", jsxs(_components.blockquote, {
      children: ["\n", jsxs(_components.p, {
        children: [jsx(_components.strong, {
          children: "注意："
        }), " 静态 attribute 是作为 html 克隆模板的一部分被创建的。固定和动态表达式随后按 JSX 绑定顺序应用。虽然这对大多数 DOM 元素来说都无所谓顺序，但是对诸如带有 ", jsx(_components.code, {
          children: "type='range'"
        }), " 的 input 元素来说，顺序很重要。绑定元素时请牢记这一点。"]
      }), "\n"]
    }), "\n", jsxs(_components.h2, {
      id: "入口",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#入口",
        children: "#"
      }), "入口"]
    }), "\n", jsxs(_components.p, {
      children: ["挂载 Solid 应用最简单方法是从 ", jsx(_components.code, {
        children: "solid-js/web"
      }), " 导入 ", jsx(_components.code, {
        children: "render"
      }), "。", jsx(_components.code, {
        children: "render"
      }), " 接收一个函数作为第一个参数，接收挂载容器作为第二个参数，并返回一个销毁方法。这个 ", jsx(_components.code, {
        children: "render"
      }), " 函数会自动创建响应式根节点根并在挂载容器中处理渲染工作。为了获得最佳性能，建议使用没有子元素的元素。"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { render } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-js/web\""
        }), ";\n\n", jsx(_components.span, {
          className: "hljs-title function_",
          children: "render"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "xml",
          children: jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "App"
            }), " />"]
          })
        }), ", ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "document"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "getElementById"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"main\""
        }), "));\n"]
      })
    }), "\n", jsxs(_components.blockquote, {
      children: ["\n", jsxs(_components.p, {
        children: [jsx(_components.strong, {
          children: "重要"
        }), " 第一个参数必须是一个函数。否则 Solid 无法正确跟踪和调度响应系统。省略函数包装器将导致您的 effect 无法运行。"]
      }), "\n"]
    }), "\n", jsxs(_components.h2, {
      id: "组件",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#组件",
        children: "#"
      }), "组件"]
    }), "\n", jsx(_components.p, {
      children: "Solid 组件通常是采用 Pascal（大写）命名风格的函数。组件第一个参数接收 props 对象，最终返回真实的 DOM 节点。"
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "Parent"
        }), " = (", jsx(_components.span, {
          className: "hljs-params"
        }), ") => (\n  ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "section"
            }), ">"]
          }), "\n    ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "Label"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "greeting"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "\"Hello\""
            }), ">"]
          }), "\n      ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "John", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "\n    ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "Label"
            }), ">"]
          }), "\n  ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "section"
            }), ">"]
          })]
        }), "\n);\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "Label"
        }), " = props => (\n  ", jsxs(_components.span, {
          className: "xml",
          children: [jsx(_components.span, {
            className: "hljs-tag",
            children: "<>"
          }), "\n    ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "{props.greeting}", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "\n    {props.children}\n  ", jsx(_components.span, {
            className: "hljs-tag",
            children: "</>"
          })]
        }), "\n);\n"]
      })
    }), "\n", jsx(_components.p, {
      children: "由于所有 JSX 节点都是真实的 DOM 节点，顶级组件的唯一职责是将这些 DOM 节点追加到容器 DOM。"
    }), "\n", jsxs(_components.h2, {
      id: "props",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#props",
        children: "#"
      }), "Props"]
    }), "\n", jsxs(_components.p, {
      children: ["与 React、Vue、Angular 以及其他框架非常相似，Solid 允许你在组件上定义 property，将数据传递给子组件。这里的父组件通过 ", jsx(_components.code, {
        children: "greeting"
      }), " property 将字符串 “Hello” 传递给 ", jsx(_components.code, {
        children: "Label"
      }), " 组件。"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "Parent"
        }), " = (", jsx(_components.span, {
          className: "hljs-params"
        }), ") => (\n  ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "section"
            }), ">"]
          }), "\n    ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "Label"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "greeting"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "\"Hello\""
            }), ">"]
          }), "\n      ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "John", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "\n    ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "Label"
            }), ">"]
          }), "\n  ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "section"
            }), ">"]
          })]
        }), "\n);\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["在上面的例子中，在 ", jsx(_components.code, {
        children: "greeting"
      }), " 上设置的值是静态的，但我们也可以设置动态值。例如："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "Parent"
        }), " = (", jsx(_components.span, {
          className: "hljs-params"
        }), ") => {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [greeting, setGreeting] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createSignal"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"Hello\""
        }), ");\n\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " (\n    ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "section"
            }), ">"]
          }), "\n      ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "Label"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "greeting"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{greeting()}"
            }), ">"]
          }), "\n        ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "John", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "\n      ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "Label"
            }), ">"]
          }), "\n    ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "section"
            }), ">"]
          })]
        }), "\n  );\n};\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["组件可以通过 ", jsx(_components.code, {
        children: "props"
      }), " 参数访问传递给它们的属性。"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "Label"
        }), " = props => (\n  ", jsxs(_components.span, {
          className: "xml",
          children: [jsx(_components.span, {
            className: "hljs-tag",
            children: "<>"
          }), "\n    ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "{props.greeting}", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "\n    {props.children}\n  ", jsx(_components.span, {
            className: "hljs-tag",
            children: "</>"
          })]
        }), "\n);\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["与其他框架不同，你不能在组件的 ", jsx(_components.code, {
        children: "props"
      }), " 上使用对象解构。这是因为 ", jsx(_components.code, {
        children: "props"
      }), " 对象在底层依赖对象的 getter 来惰性获取值。使用对象解构破坏了 props 的响应性。"]
    }), "\n", jsx(_components.p, {
      children: "这个例子展示了在 Solid 中访问 props 的正确方式："
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: [jsx(_components.span, {
          className: "hljs-comment",
          children: "// 这里 `props.name` 会按照你的期望更新"
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "MyComponent"
        }), " = props => ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "{props.name}", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          })]
        }), ";\n"]
      })
    }), "\n", jsx(_components.p, {
      children: "这个例子展示了在 Solid 中访问 props 的错误方式："
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: [jsx(_components.span, {
          className: "hljs-comment",
          children: "// 错误方式"
        }), "\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 这里，`props.name` 不会更新（即不是响应式的），因为它被解构为 `name`"
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "MyComponent"
        }), " = (", jsx(_components.span, {
          className: "hljs-params",
          children: "{ name }"
        }), ") => ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "{name}", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          })]
        }), ";\n"]
      })
    }), "\n", jsx(_components.p, {
      children: "虽然 props 对象在使用时看起来像一个普通对象（TypeScript 用户会注意到它的类型像普通对象），但实际上它是响应式的 —— 有点类似于 Signal。这有几个含义。"
    }), "\n", jsx(_components.p, {
      children: "因为与大多数 JSX 框架不同，Solid 的函数组件只执行一次（而不是每个渲染周期都执行），所以下面的示例不会按预期工作。"
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { createSignal } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-js\""
        }), ";\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "BasicComponent"
        }), " = props => {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " value = props.", jsx(_components.span, {
          className: "hljs-property",
          children: "value"
        }), " || ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"default\""
        }), ";\n\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "{value}", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          })]
        }), ";\n};\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "export"
        }), " ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "default"
        }), " ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "function"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "Form"
        }), "(", jsx(_components.span, {
          className: "hljs-params"
        }), ") {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [value, setValue] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createSignal"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"\""
        }), ");\n\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " (\n    ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "\n      ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "BasicComponent"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "value"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{value()}"
            }), " />"]
          }), "\n      ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "input"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "type"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "\"text\""
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "oninput"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{e"
            }), " =>"]
          }), " setValue(e.currentTarget.value)} />\n    ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          })]
        }), "\n  );\n}\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["在这个例子中，我们期望的是 ", jsx(_components.code, {
        children: "BasicComponent"
      }), " 显示输入到 ", jsx(_components.code, {
        children: "input"
      }), " 中的当前值。但是，提醒一下，", jsx(_components.code, {
        children: "BasicComponent"
      }), " 函数只会在组件最初创建时执行一次。此时（在创建时），", jsx(_components.code, {
        children: "props.value"
      }), " 将等于 ", jsx(_components.code, {
        children: "''"
      }), "。这意味着 ", jsx(_components.code, {
        children: "BasicComponent"
      }), " 中的 ", jsx(_components.code, {
        children: "const value"
      }), " 将解析为 ", jsx(_components.code, {
        children: "'default'"
      }), " 并且永远不会更新。虽然 ", jsx(_components.code, {
        children: "props"
      }), " 对象是响应式的，访问 ", jsx(_components.code, {
        children: "const value = props.value || 'default';"
      }), " 中的 props 就超出了 Solid 的可观察范围，因此当 props 更改时组件不会自动重新求值。"]
    }), "\n", jsx(_components.p, {
      children: "那么我们该如何解决我们的问题呢？"
    }), "\n", jsxs(_components.p, {
      children: ["嗯，一般来说，我们需要在 Solid 可以观察到的地方访问 ", jsx(_components.code, {
        children: "props"
      }), "。通常，这意味着在 JSX 内或在 ", jsx(_components.code, {
        children: "createMemo"
      }), "、", jsx(_components.code, {
        children: "createEffect"
      }), " 或 thunk(", jsx(_components.code, {
        children: "() => ..."
      }), ") 内。这里有一种按照你的预期工作的解决方案："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "BasicComponent"
        }), " = props => {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "{props.value || \"default\"}", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          })]
        }), ";\n};\n"]
      })
    }), "\n", jsx(_components.p, {
      children: "这也可以等效地提升为一个函数："
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "BasicComponent"
        }), " = props => {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "value"
        }), " = (", jsx(_components.span, {
          className: "hljs-params"
        }), ") => props.", jsx(_components.span, {
          className: "hljs-property",
          children: "value"
        }), " || ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"default\""
        }), ";\n\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "{value()}", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          })]
        }), ";\n};\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["另一种方案，如果这是一个耗时计算的场景，那应该使用 ", jsx(_components.code, {
        children: "createMemo"
      }), "。例如："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "BasicComponent"
        }), " = props => {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " value = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createMemo"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " props.", jsx(_components.span, {
          className: "hljs-property",
          children: "value"
        }), " || ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"default\""
        }), ");\n\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "{value()}", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          })]
        }), ";\n};\n"]
      })
    }), "\n", jsx(_components.p, {
      children: "或者使用工具函数"
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "BasicComponent"
        }), " = props => {\n  props = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "mergeProps"
        }), "({ ", jsx(_components.span, {
          className: "hljs-attr",
          children: "value"
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"default\""
        }), " }, props);\n\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "{props.value}", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          })]
        }), ";\n};\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["提醒一下，以下示例将 ", jsx(_components.em, {
        children: "不会"
      }), " 工作："]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: [jsx(_components.span, {
          className: "hljs-comment",
          children: "// 错误示例"
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "BasicComponent"
        }), " = props => {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " { ", jsx(_components.span, {
          className: "hljs-attr",
          children: "value"
        }), ": valueProp } = props;\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " value = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createMemo"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " valueProp || ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"default\""
        }), ");\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "{value()}", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          })]
        }), ";\n};\n\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 错误示例"
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "BasicComponent"
        }), " = props => {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " valueProp = props.", jsx(_components.span, {
          className: "hljs-property",
          children: "value"
        }), "; \n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " value = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createMemo"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " valueProp || ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"default\""
        }), ");\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "{value()}", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          })]
        }), ";\n};\n"]
      })
    }), "\n", jsx(_components.p, {
      children: "Solid 的组件是其性能的核心部分。Solid 所谓的 “消失” 组件是通过 prop 惰性求值实现的。而不是对 prop 表达式进行即时求值并传递，它推迟到了 child 中访问 prop 再执行。这样的话我们将执行推迟到最后一刻 —— 通常在 DOM 绑定，从而最大限度地提高性能。这么做不仅使层次结构扁平化而且消除了维护组件树的需要。"
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: ["<", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Component"
        }), " prop1=", jsx(_components.span, {
          className: "hljs-string",
          children: "\"static\""
        }), " prop2={state.", jsx(_components.span, {
          className: "hljs-property",
          children: "dynamic"
        }), "} />;\n\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 大致编译为："
        }), "\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 我们取消跟踪组件主体来隔离它并避免更新消耗"
        }), "\n", jsx(_components.span, {
          className: "hljs-title function_",
          children: "untrack"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), "\n  ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Component"
        }), "({\n    ", jsx(_components.span, {
          className: "hljs-attr",
          children: "prop1"
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"static\""
        }), ",\n    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 动态表达式，所以我们将其包裹在一个 getter 中"
        }), "\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "get"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "prop2"
        }), "() {\n      ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " state.", jsx(_components.span, {
          className: "hljs-property",
          children: "dynamic"
        }), ";\n    }\n  })\n);\n"]
      })
    }), "\n", jsx(_components.p, {
      children: "为了帮助保持响应性，Solid 有几个工具函数："
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: [jsx(_components.span, {
          className: "hljs-comment",
          children: "// 默认 props"
        }), "\nprops = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "mergeProps"
        }), "({ ", jsx(_components.span, {
          className: "hljs-attr",
          children: "name"
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"Smith\""
        }), " }, props);\n\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 克隆 props"
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " newProps = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "mergeProps"
        }), "(props);\n\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 合并 props"
        }), "\nprops = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "mergeProps"
        }), "(props, otherProps);\n\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 将 props 拆分为多个 props 对象"
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [local, others] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "splitProps"
        }), "(props, [", jsx(_components.span, {
          className: "hljs-string",
          children: "\"class\""
        }), "]) \n<div {...others} ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "class"
        }), "={", jsx(_components.span, {
          className: "hljs-title function_",
          children: "cx"
        }), "(local.", jsx(_components.span, {
          className: "hljs-property",
          children: "class"
        }), ", theme.", jsx(_components.span, {
          className: "hljs-property",
          children: "component"
        }), ")} /> \n"]
      })
    }), "\n", jsxs(_components.h2, {
      id: "children",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#children",
        children: "#"
      }), "Children"]
    }), "\n", jsxs(_components.p, {
      children: ["Solid 处理 JSX Children 的方式类似 React。单个 child 是 ", jsx(_components.code, {
        children: "props.children"
      }), " 上的单个值，多个 child 是通过值成员数组处理的。通常，你将 child 传递给 JSX 视图。但是，如果你想与它们交互，建议使用 ", jsx(_components.code, {
        children: "children"
      }), " 工具函数，它能够解析任何下游流程控制并返回 Memo。"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: [jsx(_components.span, {
          className: "hljs-comment",
          children: "// 单个子节点"
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "Label"
        }), " = (", jsx(_components.span, {
          className: "hljs-params",
          children: "props"
        }), ") => ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "class"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "\"label\""
            }), ">"]
          }), "Hi, { props.children }", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          })]
        }), "\n\n", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "Label"
            }), ">"]
          }), jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "span"
            }), ">"]
          }), "Josie", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "span"
            }), ">"]
          }), jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "Label"
            }), ">"]
          })]
        }), "\n\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 多个子节点"
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "List"
        }), " = (", jsx(_components.span, {
          className: "hljs-params",
          children: "props"
        }), ") => ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "{props.children}", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          })]
        }), ";\n\n", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "List"
            }), ">"]
          }), "\n  ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "First", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          }), "\n  {state.expression}\n  ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "Label"
            }), ">"]
          }), "Judith", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "Label"
            }), ">"]
          }), "\n", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "List"
            }), ">"]
          })]
        }), "\n\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 映射子节点"
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "List"
        }), " = (", jsx(_components.span, {
          className: "hljs-params",
          children: "props"
        }), ") => ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "ul"
            }), ">"]
          }), "\n  ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "For"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "each"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{props.children}"
            }), ">"]
          }), "{item => ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "li"
            }), ">"]
          }), "{item}", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "li"
            }), ">"]
          }), "}", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "For"
            }), ">"]
          }), "\n", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "ul"
            }), ">"]
          })]
        }), ";\n\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 使用工具函数修改和映射子项"
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "List"
        }), " = (", jsx(_components.span, {
          className: "hljs-params",
          children: "props"
        }), ") => {\n  ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// children 工具函数缓存值并处理所有中间反应性"
        }), "\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " memo = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "children"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " props.", jsx(_components.span, {
          className: "hljs-property",
          children: "children"
        }), ");\n  ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createEffect"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " children = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "memo"
        }), "();\n    children.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "forEach"
        }), "(", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "c"
          }), ") =>"]
        }), " c.", jsx(_components.span, {
          className: "hljs-property",
          children: "classList"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "add"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"list-child\""
        }), "))\n  })\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "ul"
            }), ">"]
          }), "\n    ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "For"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "each"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{memo()}"
            }), ">"]
          }), "{item => ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "li"
            }), ">"]
          }), "{item}", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "li"
            }), ">"]
          }), "}", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "For"
            }), ">"]
          }), "\n  ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "ul"
            }), ">"]
          })]
        }), ";\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: [jsx(_components.strong, {
        children: "重要："
      }), " Solid 将 child 标签视为耗性能的表达式，并用与动态响应式表达式相同的方式包装它们。这意味着他们利用访问 ", jsx(_components.code, {
        children: "prop"
      }), " 进行了惰性求值。在视图中使用它们之前，请小心避免多次访问它们或者进行解构。这是因为 Solid 没有大费周章地提前创建虚拟 DOM 节点然后对它们进行 diff 操作，所以这些 ", jsx(_components.code, {
        children: "props"
      }), " 的解析必须是惰性且经过斟酌的。如果你希望这样做，请使用 ", jsx(_components.code, {
        children: "children"
      }), " 工具函数，因为 ", jsx(_components.code, {
        children: "children"
      }), " 会缓存这些值。"]
    })]
  });
}
function MDXContent(props = {}) {
  const {wrapper: MDXLayout} = props.components || ({});
  return MDXLayout ? jsx(MDXLayout, Object.assign({}, props, {
    children: jsx(_createMdxContent, props)
  })) : _createMdxContent(props);
}

export { MDXContent as default, toc };
//# sourceMappingURL=rendering-c7c6d929.js.map
