var sections = [
	{
		slug: "%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97",
		title: "入门指南",
		level: 1,
		children: [
			{
				slug: "%E4%BD%BF%E7%94%A8-solid",
				title: "使用 Solid",
				level: 2,
				children: [
				]
			},
			{
				slug: "%E5%AD%A6%E4%B9%A0-solid",
				title: "学习 Solid",
				level: 2,
				children: [
				]
			},
			{
				slug: "solid-%E7%90%86%E5%BF%B5",
				title: "Solid 理念",
				level: 2,
				children: [
					{
						slug: "1.-%E5%A3%B0%E6%98%8E%E5%BC%8F%E6%95%B0%E6%8D%AE",
						title: "1. 声明式数据",
						level: 3,
						children: [
						]
					},
					{
						slug: "2.-%E6%B6%88%E5%A4%B1%E7%9A%84%E7%BB%84%E4%BB%B6",
						title: "2. 消失的组件",
						level: 3,
						children: [
						]
					},
					{
						slug: "3.-%E8%AF%BB%2F%E5%86%99-%E5%88%86%E7%A6%BB",
						title: "3. 读/写 分离",
						level: 3,
						children: [
						]
					},
					{
						slug: "4.-%E7%AE%80%E5%8D%95%E8%83%9C%E4%BA%8E%E5%AE%B9%E6%98%93",
						title: "4. 简单胜于容易",
						level: 3,
						children: [
						]
					}
				]
			},
			{
				slug: "web-%E7%BB%84%E4%BB%B6",
				title: "Web 组件",
				level: 2,
				children: [
				]
			},
			{
				slug: "%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%B8%B2%E6%9F%93",
				title: "服务端渲染",
				level: 2,
				children: [
				]
			},
			{
				slug: "%E6%97%A0%E7%BC%96%E8%AF%91%3F",
				title: "无编译?",
				level: 2,
				children: [
				]
			}
		]
	},
	{
		slug: "%E5%93%8D%E5%BA%94%E6%80%A7",
		title: "响应性",
		level: 1,
		children: [
			{
				slug: "primitives-%E7%AE%80%E4%BB%8B",
				title: "Primitives 简介",
				level: 2,
				children: [
				]
			},
			{
				slug: "%E5%A6%82%E4%BD%95%E8%BF%90%E4%BD%9C%E7%9A%84%EF%BC%9F",
				title: "如何运作的？",
				level: 2,
				children: [
				]
			},
			{
				slug: "%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9",
				title: "注意事项",
				level: 2,
				children: [
				]
			}
		]
	},
	{
		slug: "%E6%B8%B2%E6%9F%93",
		title: "渲染",
		level: 1,
		children: [
			{
				slug: "jsx-%E7%BC%96%E8%AF%91",
				title: "JSX 编译",
				level: 2,
				children: [
				]
			},
			{
				slug: "attributes-%E5%92%8C-props",
				title: "Attributes 和 Props",
				level: 2,
				children: [
				]
			},
			{
				slug: "%E5%85%A5%E5%8F%A3",
				title: "入口",
				level: 2,
				children: [
				]
			},
			{
				slug: "%E7%BB%84%E4%BB%B6",
				title: "组件",
				level: 2,
				children: [
				]
			},
			{
				slug: "props",
				title: "Props",
				level: 2,
				children: [
				]
			},
			{
				slug: "children",
				title: "Children",
				level: 2,
				children: [
				]
			}
		]
	},
	{
		slug: "ssr",
		title: "SSR",
		level: 1,
		children: [
			{
				slug: "%E6%B3%A8%E6%B0%B4%E8%84%9A%E6%9C%AC",
				title: "注水脚本",
				level: 2,
				children: [
				]
			},
			{
				slug: "%E5%BC%82%E6%AD%A5%E5%92%8C%E6%B5%81%E5%BC%8F-ssr",
				title: "异步和流式 SSR",
				level: 2,
				children: [
				]
			},
			{
				slug: "ssr-%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9",
				title: "SSR 注意事项",
				level: 2,
				children: [
				]
			},
			{
				slug: "ssr-%E5%85%A5%E9%97%A8",
				title: "SSR 入门",
				level: 2,
				children: [
				]
			},
			{
				slug: "%E9%9D%99%E6%80%81%E7%AB%99%E7%82%B9%E7%94%9F%E6%88%90%E5%85%A5%E9%97%A8",
				title: "静态站点生成入门",
				level: 2,
				children: [
				]
			}
		]
	}
];
var content = "<section class=\"mt-10\"><h1 id=\"%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97\">#</a> 入门指南</h1><h2 id=\"%E4%BD%BF%E7%94%A8-solid\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#%E4%BD%BF%E7%94%A8-solid\">#</a> 使用 Solid</h2><p>到目前为止，开始使用 Solid 的最简单方法是在线使用。在我们的 REPL(<a href=\"https://playground.solidjs.com\">https://playground.solidjs.com</a>) 上尝试各种想法是一种不错方式。另外你也可以在 <a href=\"https://codesandbox.io/\">https://codesandbox.io/</a> 修改我们的示例代码。</p><p>你也可以通过在终端中运行以下命令来创建并启动简单的 Vite 模板项目：</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">&gt;</span><span style=\"color:#24292e\"> npx degit solidjs/templates/js my-app</span></span>\n<span class=\"line\"><span style=\"color:#d73a49\">&gt;</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">cd</span><span style=\"color:#24292e\"> my-app</span></span>\n<span class=\"line\"><span style=\"color:#d73a49\">&gt;</span><span style=\"color:#24292e\"> npm i </span><span style=\"color:#6a737d\"># or yarn or pnpm</span></span>\n<span class=\"line\"><span style=\"color:#d73a49\">&gt;</span><span style=\"color:#24292e\"> npm run dev </span><span style=\"color:#6a737d\"># or yarn or pnpm</span></span>\n<span class=\"line\"></span></code></pre><p>使用 TypeScript ：</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">&gt;</span><span style=\"color:#24292e\"> npx degit solidjs/templates/ts my-app</span></span>\n<span class=\"line\"><span style=\"color:#d73a49\">&gt;</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">cd</span><span style=\"color:#24292e\"> my-app</span></span>\n<span class=\"line\"><span style=\"color:#d73a49\">&gt;</span><span style=\"color:#24292e\"> npm i </span><span style=\"color:#6a737d\"># or yarn or pnpm</span></span>\n<span class=\"line\"><span style=\"color:#d73a49\">&gt;</span><span style=\"color:#24292e\"> npm run dev </span><span style=\"color:#6a737d\"># or yarn or pnpm</span></span>\n<span class=\"line\"></span></code></pre><h2 id=\"%E5%AD%A6%E4%B9%A0-solid\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#%E5%AD%A6%E4%B9%A0-solid\">#</a> 学习 Solid</h2><p>Solid 到处都是可组合的小片段，用这些片段用来构建应用块。这些部分主要由许多浅显的顶级 API 的函数组成。幸运的是，你无需了解其中的大部分内容即可开始使用。</p><p>你可以使用组件和响应式 Primitives 这两种主流方式来构建区块</p><p>组件是接受 props 对象并返回 JSX 元素（包括原生 DOM 元素和其他组件）的函数。它们可以用大驼峰拼写表示为 JSX 元素</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">function</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">MyComponent</span><span style=\"color:#24292e\">(</span><span style=\"color:#e36209\">props</span><span style=\"color:#24292e\">) {</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">return</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;Hello {props.name}&lt;/</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">}</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#24292e\">&lt;</span><span style=\"color:#22863a\">MyComponent</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">name</span><span style=\"color:#d73a49\">=</span><span style=\"color:#032f62\">&quot;Solid&quot;</span><span style=\"color:#24292e\"> /&gt;;</span></span>\n<span class=\"line\"></span></code></pre><p>组件是轻量级的，因为它们本身没有状态，也没有实例。相反，它们充当 DOM 元素和响应式 primitives 的工厂函数</p><p>Solid 的细粒度响应式建立在 3 个简单的 primitives 之上：Signals、Memos 和 Effects。它们共同构成了一个自动跟踪同步引擎，可确保你的视图保持最新。响应式计算采用了简单包装函数表达式的形式，另外他们是同步执行的</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> [</span><span style=\"color:#005cc5\">first</span><span style=\"color:#24292e\">, </span><span style=\"color:#005cc5\">setFirst</span><span style=\"color:#24292e\">] </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">createSignal</span><span style=\"color:#24292e\">(</span><span style=\"color:#032f62\">&quot;JSON&quot;</span><span style=\"color:#24292e\">);</span></span>\n<span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> [</span><span style=\"color:#005cc5\">last</span><span style=\"color:#24292e\">, </span><span style=\"color:#005cc5\">setLast</span><span style=\"color:#24292e\">] </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">createSignal</span><span style=\"color:#24292e\">(</span><span style=\"color:#032f62\">&quot;Bourne&quot;</span><span style=\"color:#24292e\">);</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6f42c1\">createEffect</span><span style=\"color:#24292e\">(() </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> console.</span><span style=\"color:#6f42c1\">log</span><span style=\"color:#24292e\">(</span><span style=\"color:#032f62\">`${</span><span style=\"color:#6f42c1\">first</span><span style=\"color:#032f62\">()</span><span style=\"color:#032f62\">} ${</span><span style=\"color:#6f42c1\">last</span><span style=\"color:#032f62\">()</span><span style=\"color:#032f62\">}`</span><span style=\"color:#24292e\">));</span></span>\n<span class=\"line\"></span></code></pre><p>你可以在以下内容中了解更多 <a href=\"#%E5%93%8D%E5%BA%94%E6%80%A7\">Solid's Reactivity</a> 和 <a href=\"#%E6%B8%B2%E6%9F%93\">Solid's Rendering</a>.</p><h2 id=\"solid-%E7%90%86%E5%BF%B5\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#solid-%E7%90%86%E5%BF%B5\">#</a> Solid 理念</h2><p>Solid 的设计提出了一些可以帮助我们最好地构建网站和应用程序的原则和价值观。当你了解 Solid 背后的哲学时，学习和使用 Solid 会更容易。</p><h3 id=\"1.-%E5%A3%B0%E6%98%8E%E5%BC%8F%E6%95%B0%E6%8D%AE\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#1.-%E5%A3%B0%E6%98%8E%E5%BC%8F%E6%95%B0%E6%8D%AE\">#</a> 1. 声明式数据</h3><p>声明式数据是将数据行为的描述与其声明联系起来的实践。这允许我们通过将数据行为的所有方面打包在一个地方来轻松组合。</p><h3 id=\"2.-%E6%B6%88%E5%A4%B1%E7%9A%84%E7%BB%84%E4%BB%B6\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#2.-%E6%B6%88%E5%A4%B1%E7%9A%84%E7%BB%84%E4%BB%B6\">#</a> 2. 消失的组件</h3><p>在不考虑更新的情况下构建组件已经够难的了。Solid 的组件更新是彼此完全独立的。组件函数被调用一次，然后就不再存在。组件的存在是为了组织你的代码，而不是其他。</p><h3 id=\"3.-%E8%AF%BB%2F%E5%86%99-%E5%88%86%E7%A6%BB\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#3.-%E8%AF%BB%2F%E5%86%99-%E5%88%86%E7%A6%BB\">#</a> 3. 读/写 分离</h3><p>精确的控制和可预测性有助于打造更好的系统。我们不需要真正的不变性来强制执行单向数据流，只需要能够有意识到哪些消费者可能会写，哪些可能不会。</p><h3 id=\"4.-%E7%AE%80%E5%8D%95%E8%83%9C%E4%BA%8E%E5%AE%B9%E6%98%93\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#4.-%E7%AE%80%E5%8D%95%E8%83%9C%E4%BA%8E%E5%AE%B9%E6%98%93\">#</a> 4. 简单胜于容易</h3><p>细粒度响应性教会我们：明确且一致的约定即使需要更多努力也是值得的。且有必要提供最少的工具作为构建的基础。</p><h2 id=\"web-%E7%BB%84%E4%BB%B6\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#web-%E7%BB%84%E4%BB%B6\">#</a> Web 组件</h2><p>Solid 生而将 Web 组件作为一等公民。随着时间的推移，它的设计不断发展，目标也发生了变化。然而，Solid 仍然是编写 Web 组件的好选择。<a href=\"https://github.com/solidjs/solid/tree/main/packages/solid-element\">Solid Element</a> 允许你编写和包装 Solid 的函数组件以生成小型且高性能的 Web 组件。在 Solid 应用程序中，Solid Element 仍然能够利用 Solid 的 Context API，并且 Solid 的 Portals 支持隔离样式的 Shadow DOM 。</p><h2 id=\"%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%B8%B2%E6%9F%93\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%B8%B2%E6%9F%93\">#</a> 服务端渲染</h2><p>Solid 拥有动态的服务器端渲染解决方案，可实现真正的同构开发体验。通过使用我们的 Resource primitive，很容易进行异步数据请求，更重要的是，我们也可以在客户端和浏览器之间自动序列化和同步。</p><p>由于 Solid 支持服务器上的异步和流式渲染，因此你可以以一种方式编写代码并让它在服务器上执行。这个特性类似 <a href=\"https://reactjs.org/docs/concurrent-mode-suspense.html#approach-3-render-as-you-fetch-using-suspense\">render-as-you-fetch</a>，并且代码分割特性也适用于 Solid。</p><p>更多信息，请阅读 <a href=\"#ssr\">服务端渲染指南</a>.</p><h2 id=\"%E6%97%A0%E7%BC%96%E8%AF%91%3F\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#%E6%97%A0%E7%BC%96%E8%AF%91%3F\">#</a> 无编译?</h2><p>不喜欢 JSX？不介意手动包装表达式、性能更差和包大小更大吗？你可以采用另一种方案：在非编译环境中使用标记模板字面量或 HyperScript 创建 Solid 应用。</p><p>你可以直接在浏览器中运行下面代码 <a href=\"https://www.skypack.dev/\">Skypack</a>:</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#24292e\">&lt;</span><span style=\"color:#22863a\">html</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  &lt;</span><span style=\"color:#22863a\">body</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    &lt;</span><span style=\"color:#22863a\">script</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">type</span><span style=\"color:#24292e\">=</span><span style=\"color:#032f62\">&quot;module&quot;</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">      </span><span style=\"color:#d73a49\">import</span><span style=\"color:#24292e\"> { createSignal, onCleanup } </span><span style=\"color:#d73a49\">from</span><span style=\"color:#24292e\"> </span><span style=\"color:#032f62\">&quot;https://cdn.skypack.dev/solid-js&quot;</span><span style=\"color:#24292e\">;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">      </span><span style=\"color:#d73a49\">import</span><span style=\"color:#24292e\"> { render } </span><span style=\"color:#d73a49\">from</span><span style=\"color:#24292e\"> </span><span style=\"color:#032f62\">&quot;https://cdn.skypack.dev/solid-js/web&quot;</span><span style=\"color:#24292e\">;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">      </span><span style=\"color:#d73a49\">import</span><span style=\"color:#24292e\"> html </span><span style=\"color:#d73a49\">from</span><span style=\"color:#24292e\"> </span><span style=\"color:#032f62\">&quot;https://cdn.skypack.dev/solid-js/html&quot;</span><span style=\"color:#24292e\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#24292e\">      </span><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">App</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> () </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> {</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">        </span><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> [</span><span style=\"color:#005cc5\">count</span><span style=\"color:#24292e\">, </span><span style=\"color:#005cc5\">setCount</span><span style=\"color:#24292e\">] </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">createSignal</span><span style=\"color:#24292e\">(</span><span style=\"color:#005cc5\">0</span><span style=\"color:#24292e\">),</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">          </span><span style=\"color:#005cc5\">timer</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">setInterval</span><span style=\"color:#24292e\">(() </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">setCount</span><span style=\"color:#24292e\">(</span><span style=\"color:#6f42c1\">count</span><span style=\"color:#24292e\">() </span><span style=\"color:#d73a49\">+</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">1</span><span style=\"color:#24292e\">), </span><span style=\"color:#005cc5\">1000</span><span style=\"color:#24292e\">);</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">        </span><span style=\"color:#6f42c1\">onCleanup</span><span style=\"color:#24292e\">(() </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">clearInterval</span><span style=\"color:#24292e\">(timer));</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">        </span><span style=\"color:#d73a49\">return</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">html</span><span style=\"color:#032f62\">`&lt;div&gt;${</span><span style=\"color:#24292e\">count</span><span style=\"color:#032f62\">}&lt;/div&gt;`</span><span style=\"color:#24292e\">;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">      };</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">      </span><span style=\"color:#6f42c1\">render</span><span style=\"color:#24292e\">(App, document.body);</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    &lt;/</span><span style=\"color:#22863a\">script</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  &lt;/</span><span style=\"color:#22863a\">body</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">&lt;/</span><span style=\"color:#22863a\">html</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"></span></code></pre><p>请记住，你仍然需要相应的 DOM 表达式库才能配合 TypeScript 使用。你也可以搭配 <a href=\"https://github.com/ryansolid/dom-expressions/tree/main/packages/lit-dom-expressions\">Lit DOM Expressions</a> 使用标签模板字面量或者搭配 <a href=\"https://github.com/ryansolid/dom-expressions/tree/main/packages/hyper-dom-expressions\">Hyper DOM Expressions</a> 使用 HyperScript。</p></section><section class=\"mt-10\"><h1 id=\"%E5%93%8D%E5%BA%94%E6%80%A7\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#%E5%93%8D%E5%BA%94%E6%80%A7\">#</a> 响应性</h1><p>Solid 的数据管理建立在一系列灵活的响应式 primitive 之上，这些 primitive 负责所有的更新。它采用与 MobX 或 Vue 非常相似的方法，只是它没有和虚拟 DOM 进行颗粒度绑定。当你访问你的 Effects 和 JSX 视图代码中的响应式值时，它会自动跟踪依赖项。</p><p>Solid 的 primitives 通常以 <code>create</code> 调用的形式出现，通常返回元组，其中通常第一个元素是可读 primitive，第二个元素是 setter。通常通过 primitive 名称来引用可读部分。</p><p>这是一个基础的自动递增计数器，它根据设置的 <code>count</code> Signal 进行更新</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">import</span><span style=\"color:#24292e\"> { createSignal, onCleanup } </span><span style=\"color:#d73a49\">from</span><span style=\"color:#24292e\"> </span><span style=\"color:#032f62\">&quot;solid-js&quot;</span><span style=\"color:#24292e\">;</span></span>\n<span class=\"line\"><span style=\"color:#d73a49\">import</span><span style=\"color:#24292e\"> { render } </span><span style=\"color:#d73a49\">from</span><span style=\"color:#24292e\"> </span><span style=\"color:#032f62\">&quot;solid-js/web&quot;</span><span style=\"color:#24292e\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">App</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> () </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> {</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> [</span><span style=\"color:#005cc5\">count</span><span style=\"color:#24292e\">, </span><span style=\"color:#005cc5\">setCount</span><span style=\"color:#24292e\">] </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">createSignal</span><span style=\"color:#24292e\">(</span><span style=\"color:#005cc5\">0</span><span style=\"color:#24292e\">),</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    </span><span style=\"color:#005cc5\">timer</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">setInterval</span><span style=\"color:#24292e\">(() </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">setCount</span><span style=\"color:#24292e\">(</span><span style=\"color:#6f42c1\">count</span><span style=\"color:#24292e\">() </span><span style=\"color:#d73a49\">+</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">1</span><span style=\"color:#24292e\">), </span><span style=\"color:#005cc5\">1000</span><span style=\"color:#24292e\">);</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#6f42c1\">onCleanup</span><span style=\"color:#24292e\">(() </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">clearInterval</span><span style=\"color:#24292e\">(timer));</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">return</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;{</span><span style=\"color:#6f42c1\">count</span><span style=\"color:#24292e\">()}&lt;/</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">};</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6f42c1\">render</span><span style=\"color:#24292e\">(() </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">App</span><span style=\"color:#24292e\"> /&gt;, document.</span><span style=\"color:#6f42c1\">getElementById</span><span style=\"color:#24292e\">(</span><span style=\"color:#032f62\">&quot;app&quot;</span><span style=\"color:#24292e\">));</span></span>\n<span class=\"line\"></span></code></pre><h2 id=\"primitives-%E7%AE%80%E4%BB%8B\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#primitives-%E7%AE%80%E4%BB%8B\">#</a> Primitives 简介</h2><p>Solid 由 3 个主要 Primitive 组成，即 Signal、Memo 和 Effect。它们的核心是观察者模式，其中通过封装 Memos 和 Effect 来跟踪 Signal（以及 Memo）。</p><p>Signal 是最简单的 primitive。它们包含值，以及 get 和 set 函数，因此我们可以在读取和写入的时候进行拦截</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> [</span><span style=\"color:#005cc5\">count</span><span style=\"color:#24292e\">, </span><span style=\"color:#005cc5\">setCount</span><span style=\"color:#24292e\">] </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">createSignal</span><span style=\"color:#24292e\">(</span><span style=\"color:#005cc5\">0</span><span style=\"color:#24292e\">);</span></span>\n<span class=\"line\"></span></code></pre><p>Effect 是读取 Signal 的封装函数，并且会在依赖的 Signal 值发生变化时重新执行。这对于创建诸如渲染之类副作用很有用。</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#6f42c1\">createEffect</span><span style=\"color:#24292e\">(() </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> console.</span><span style=\"color:#6f42c1\">log</span><span style=\"color:#24292e\">(</span><span style=\"color:#032f62\">&quot;The latest count is&quot;</span><span style=\"color:#24292e\">, </span><span style=\"color:#6f42c1\">count</span><span style=\"color:#24292e\">()));</span></span>\n<span class=\"line\"></span></code></pre><p>最后，Memo 是缓存的派生值。它们有着 Signal 和 Effect 相同的属性。Memo 跟踪自己的 Signal，仅在这些 Signal 发生变化时重新执行，并且本身是可跟踪的 Signal。</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">fullName</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">createMemo</span><span style=\"color:#24292e\">(() </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> </span><span style=\"color:#032f62\">`${</span><span style=\"color:#6f42c1\">firstName</span><span style=\"color:#032f62\">()</span><span style=\"color:#032f62\">} ${</span><span style=\"color:#6f42c1\">lastName</span><span style=\"color:#032f62\">()</span><span style=\"color:#032f62\">}`</span><span style=\"color:#24292e\">);</span></span>\n<span class=\"line\"></span></code></pre><h2 id=\"%E5%A6%82%E4%BD%95%E8%BF%90%E4%BD%9C%E7%9A%84%EF%BC%9F\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#%E5%A6%82%E4%BD%95%E8%BF%90%E4%BD%9C%E7%9A%84%EF%BC%9F\">#</a> 如何运作的？</h2><p>Signal 作为事件发射器持有订阅列表。每当它们的值发生变化时，它们都会通知其订阅者。</p><p>更有趣的是这些订阅是如何发生的。Solid 使用自动依赖跟踪。数据一旦变化，更新会自动发生。</p><p>里面利用了运行时的全局堆栈的小技巧来实现。在 Effect 或 Memo 执行（或重新执行）开发人员编写函数之前，它会将自己压入该堆栈。然后读取的任何 Signal 检查堆栈上是否有当前侦听器，如果有，则将该侦听器添加到其订阅中。</p><p>你可以通过下面代码进行思考：</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">function</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">createSignal</span><span style=\"color:#24292e\">(</span><span style=\"color:#e36209\">value</span><span style=\"color:#24292e\">) {</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">subscribers</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">new</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">Set</span><span style=\"color:#24292e\">();</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">read</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> () </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> {</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    </span><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">listener</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">getCurrentListener</span><span style=\"color:#24292e\">();</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    </span><span style=\"color:#d73a49\">if</span><span style=\"color:#24292e\"> (listener) subscribers.</span><span style=\"color:#6f42c1\">add</span><span style=\"color:#24292e\">(listener);</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    </span><span style=\"color:#d73a49\">return</span><span style=\"color:#24292e\"> value;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  };</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">write</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#e36209\">nextValue</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> {</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    value </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> nextValue;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    </span><span style=\"color:#d73a49\">for</span><span style=\"color:#24292e\"> (</span><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">sub</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">of</span><span style=\"color:#24292e\"> subscribers) sub.</span><span style=\"color:#6f42c1\">run</span><span style=\"color:#24292e\">();</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  };</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">return</span><span style=\"color:#24292e\"> [read, write];</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">}</span></span>\n<span class=\"line\"></span></code></pre><p>现在，每当我们更新信号时，我们就知道要重新运行哪些 Effect。简单而有效。实际的实现要复杂得多，但这就是内部实现的思路。</p><p>想要更详细地了解响应性的工作原理，下面有些有用的文章：</p><p><a href=\"https://dev.to/ryansolid/a-hands-on-introduction-to-fine-grained-reactivity-3ndf\">A Hands-on Introduction to Fine-Grained Reactivity</a></p><p><a href=\"https://dev.to/ryansolid/building-a-reactive-library-from-scratch-1i0p\">Building a Reactive Library from Scratch</a></p><p><a href=\"https://indepth.dev/posts/1289/solidjs-reactivity-to-rendering\">SolidJS: Reactivity to Rendering</a></p><h2 id=\"%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9\">#</a> 注意事项</h2><p>这种响应式的方法非常强大且灵活。它可以处理不同条件分支下动态执行代码的依赖变更。它还可以在不同的间接层级起作用。在跟踪作用域内执行的任意函数都会被跟踪。</p><p>但是，我们必须注意一些关键特征和权衡。</p><ol> <li> <p>所有响应性都从函数调用中跟踪的，无论是直接的还是隐藏在 getter/proxy 下通过访问属性触发的。这意味着你在何处访问响应式对象的属性很重要。</p> </li> <li> <p>流程控制下的组件和回调函数不会跟踪作用域且只执行一次。这意味着在组件中解构或在顶层处理逻辑将不会触发重新执行。你必须从其他响应式 primitive 或 JSX 中访问这些 Signal、Store 和属性，以便重新运行对应部分代码。</p> </li> <li> <p>这种方法只能进行同步跟踪。如果你使用 setTimeout 或在的 Effect 中使用异步函数，那么 Solid 并不会跟踪异步执行的代码。</p> </li> </ol></section><section class=\"mt-10\"><h1 id=\"%E6%B8%B2%E6%9F%93\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#%E6%B8%B2%E6%9F%93\">#</a> 渲染</h1><p>Solid 支持 JSX、标签模板字面量 和 Solid HyperScript 变体这 3 种模板形式。其中 JSX 是主流，这是因为 JSX 是一门优秀的编译型 DSL。它有着清晰的语法，支持 TypeScript，可与 Babel 配合使用，并支持其他工具，如代码语法高亮和 Prettier。使用一种基本上免费为你提供所有功能的工具是相当务实的。JSX 作为一个编译的解决方案，它提供了很好的开发体验。当你可以使用一门如此广受支持且支持自定义语法的 DSL 时，有什么可纠结的呢？</p><h2 id=\"jsx-%E7%BC%96%E8%AF%91\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#jsx-%E7%BC%96%E8%AF%91\">#</a> JSX 编译</h2><p>渲染涉及到将 JSX 模板预编译为优化的原生 js 代码。JSX 代码会被构造成：</p><ul> <li>在每个实例都会被克隆的模板 DOM 元素</li> <li>仅使用 firstChild 和 nextSibling 的一系列引用声明</li> <li>更新已创建元素的细粒度计算</li> </ul><p>与使用 document.createElement 一个一个地创建每个元素相比，这种方法的性能更高，生成的代码更少。</p><h2 id=\"attributes-%E5%92%8C-props\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#attributes-%E5%92%8C-props\">#</a> Attributes 和 Props</h2><p>Solid 尝试尽可能地与 HTML 的 attribute 保持一致，包括不区分属性的大小写。</p><p>原生元素 JSX 上的大多数 attribute 都被设置为 DOM attribute。静态值会直接内置到克隆模板中。也有例外，诸如 <code>class</code>、<code>style</code>、<code>value</code>、<code>innerHTML</code>之类会提供了额外的功能。</p><p>但是，自定义元素（内置的原生元素除外）在动态时默视为认为 property。这是为了处理更复杂的数据类型。为了遵循习惯，Solid 直接将蛇形命名（<code>some-attr</code>）转化为驼峰命名（<code>someAttr</code>）。</p><p>但是，也可以使用命名空间指令直接控制该行为。你可以使用 <code>attr:</code> 指定 attribute 或者使用 <code>prop:</code> 指定 property</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#24292e\">&lt;</span><span style=\"color:#22863a\">my-element</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">prop</span><span style=\"color:#24292e\">:</span><span style=\"color:#005cc5\">UniqACC</span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\">{state.value} </span><span style=\"color:#005cc5\">attr</span><span style=\"color:#24292e\">:</span><span style=\"color:#005cc5\">title</span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\">{state.title} /&gt;</span></span>\n<span class=\"line\"></span></code></pre><blockquote> <p><strong>注意：</strong> 静态 attribute 是作为 html 克隆模板的一部分被创建的。固定和动态表达式随后按 JSX 绑定顺序应用。虽然这对大多数 DOM 元素来说都无所谓顺序，但是对诸如带有 <code>type='range'</code> 的 input 元素来说，顺序很重要。绑定元素时请牢记这一点。</p> </blockquote><h2 id=\"%E5%85%A5%E5%8F%A3\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#%E5%85%A5%E5%8F%A3\">#</a> 入口</h2><p>挂载 Solid 应用最简单方法是从 <code>solid-js/web</code> 导入 <code>render</code>。<code>render</code> 接收一个函数作为第一个参数，接收挂载容器作为第二个参数，并返回一个销毁方法。这个 <code>render</code> 函数会自动创建响应式根节点根并在挂载容器中处理渲染工作。为了获得最佳性能，建议使用没有子元素的元素。</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">import</span><span style=\"color:#24292e\"> { render } </span><span style=\"color:#d73a49\">from</span><span style=\"color:#24292e\"> </span><span style=\"color:#032f62\">&quot;solid-js/web&quot;</span><span style=\"color:#24292e\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6f42c1\">render</span><span style=\"color:#24292e\">(() </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">App</span><span style=\"color:#24292e\"> /&gt;, document.</span><span style=\"color:#6f42c1\">getElementById</span><span style=\"color:#24292e\">(</span><span style=\"color:#032f62\">&quot;main&quot;</span><span style=\"color:#24292e\">));</span></span>\n<span class=\"line\"></span></code></pre><blockquote> <p><strong>重要</strong> 第一个参数必须是一个函数。否则 Solid 无法正确跟踪和调度响应系统。偷懒将导致你的 Effect 无法运行。</p> </blockquote><h2 id=\"%E7%BB%84%E4%BB%B6\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#%E7%BB%84%E4%BB%B6\">#</a> 组件</h2><p>Solid 组件通常是采用 Pascal（大写）命名风格的函数。组件第一个参数接收 props 对象，最终返回真实的 DOM 节点。</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">Parent</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> () </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> (</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  &lt;</span><span style=\"color:#22863a\">section</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    &lt;</span><span style=\"color:#22863a\">Label</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">greeting</span><span style=\"color:#d73a49\">=</span><span style=\"color:#032f62\">&quot;Hello&quot;</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">      &lt;</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;John&lt;/</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    &lt;/</span><span style=\"color:#22863a\">Label</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  &lt;/</span><span style=\"color:#22863a\">section</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">);</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">Label</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#e36209\">props</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> (</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  &lt;&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    &lt;</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;{props.greeting}&lt;/</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    {props.children}</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  &lt;/&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">);</span></span>\n<span class=\"line\"></span></code></pre><p>由于所有 JSX 节点都是真实的 DOM 节点，顶级组件的唯一职责是将这些 DOM 节点追加到容器 DOM。</p><h2 id=\"props\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#props\">#</a> Props</h2><p>与 React、Vue、Angular 以及其他框架非常相似，Solid 允许你在组件上定义 property，将数据传递给子组件。这里的父组件通过 <code>greeting</code> property 将字符串 “Hello” 传递给 <code>Label</code> 组件。</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">Parent</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> () </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> (</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  &lt;</span><span style=\"color:#22863a\">section</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    &lt;</span><span style=\"color:#22863a\">Label</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">greeting</span><span style=\"color:#d73a49\">=</span><span style=\"color:#032f62\">&quot;Hello&quot;</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">      &lt;</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;John&lt;/</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    &lt;/</span><span style=\"color:#22863a\">Label</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  &lt;/</span><span style=\"color:#22863a\">section</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">);</span></span>\n<span class=\"line\"></span></code></pre><p>在上面的例子中，在 <code>greeting</code> 上设置的值是静态的，但我们也可以设置动态值。例如：</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">Parent</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> () </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> {</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> [</span><span style=\"color:#005cc5\">greeting</span><span style=\"color:#24292e\">, </span><span style=\"color:#005cc5\">setGreeting</span><span style=\"color:#24292e\">] </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">createSignal</span><span style=\"color:#24292e\">(</span><span style=\"color:#032f62\">&quot;Hello&quot;</span><span style=\"color:#24292e\">);</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">return</span><span style=\"color:#24292e\"> (</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    &lt;</span><span style=\"color:#22863a\">section</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">      &lt;</span><span style=\"color:#22863a\">Label</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">greeting</span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\">{</span><span style=\"color:#6f42c1\">greeting</span><span style=\"color:#24292e\">()}&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">        &lt;</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;John&lt;/</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">      &lt;/</span><span style=\"color:#22863a\">Label</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    &lt;/</span><span style=\"color:#22863a\">section</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  );</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">};</span></span>\n<span class=\"line\"></span></code></pre><p>组件可以通过 <code>props</code> 参数访问传递给它们的属性。</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">Label</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#e36209\">props</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> (</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  &lt;&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    &lt;</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;{props.greeting}&lt;/</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    {props.children}</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  &lt;/&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">);</span></span>\n<span class=\"line\"></span></code></pre><p>与其他框架不同，你不能在组件的 <code>props</code> 上使用对象解构。这是因为 <code>props</code> 对象在底层依赖对象的 getter 来惰性获取值。使用对象解构破坏了 props 的响应性。</p><p>这个例子展示了在 Solid 中访问 props 的正确方式：</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#6a737d\">// 这里 `props.name` 会按照你的期望更新</span></span>\n<span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">MyComponent</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#e36209\">props</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;{props.name}&lt;/</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;;</span></span>\n<span class=\"line\"></span></code></pre><p>这个例子展示了在 Solid 中访问 props 的错误方式：</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#6a737d\">// 错误方式</span></span>\n<span class=\"line\"><span style=\"color:#6a737d\">// 这里，`props.name` 不会更新（即不是响应式的），因为它被解构为 `name`</span></span>\n<span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">MyComponent</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> ({ </span><span style=\"color:#e36209\">name</span><span style=\"color:#24292e\"> }) </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;{name}&lt;/</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;;</span></span>\n<span class=\"line\"></span></code></pre><p>虽然 props 对象在使用时看起来像一个普通对象（Typescript 用户会注意到它的类型像普通对象），但实际上它是响应式的 —— 有点类似于 Signal。这有几个含义。</p><p>因为与大多数 JSX 框架不同，Solid 的函数组件只执行一次（而不是每个渲染周期都执行），所以下面的示例不会按预期工作。</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">import</span><span style=\"color:#24292e\"> { createSignal } </span><span style=\"color:#d73a49\">from</span><span style=\"color:#24292e\"> </span><span style=\"color:#032f62\">&quot;solid-js&quot;</span><span style=\"color:#24292e\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">BasicComponent</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#e36209\">props</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> {</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">value</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> props.value </span><span style=\"color:#d73a49\">||</span><span style=\"color:#24292e\"> </span><span style=\"color:#032f62\">&quot;default&quot;</span><span style=\"color:#24292e\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">return</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;{value}&lt;/</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">};</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#d73a49\">export</span><span style=\"color:#e36209\"> </span><span style=\"color:#d73a49\">default</span><span style=\"color:#e36209\"> </span><span style=\"color:#d73a49\">function</span><span style=\"color:#e36209\"> </span><span style=\"color:#6f42c1\">Form</span><span style=\"color:#e36209\">() </span><span style=\"color:#24292e\">{</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> [</span><span style=\"color:#005cc5\">value</span><span style=\"color:#24292e\">, </span><span style=\"color:#005cc5\">setValue</span><span style=\"color:#24292e\">] </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">createSignal</span><span style=\"color:#24292e\">(</span><span style=\"color:#032f62\">&quot;&quot;</span><span style=\"color:#24292e\">);</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">return</span><span style=\"color:#24292e\"> (</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    &lt;</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">      &lt;</span><span style=\"color:#22863a\">BasicComponent</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">value</span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\">{</span><span style=\"color:#6f42c1\">value</span><span style=\"color:#24292e\">()} /&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">      &lt;</span><span style=\"color:#22863a\">input</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">type</span><span style=\"color:#d73a49\">=</span><span style=\"color:#032f62\">&quot;text&quot;</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">oninput</span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\">{</span><span style=\"color:#e36209\">e</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">setValue</span><span style=\"color:#24292e\">(e.currentTarget.value)} /&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    &lt;/</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  );</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">}</span></span>\n<span class=\"line\"></span></code></pre><p>在这个例子中，我们期望的是 <code>BasicComponent</code> 显示输入到 <code>input</code> 中的当前值。但是，提醒一下，<code>BasicComponent</code> 函数只会在组件最初创建时执行一次。此时（在创建时），<code>props.value</code> 将等于 <code>''</code>。这意味着 <code>BasicComponent</code> 中的 <code>const value</code> 将解析为 <code>'default'</code> 并且永远不会更新。虽然 <code>props</code> 对象是响应式的，访问 <code>const value = props.value || 'default';</code> 中的 props 就超出了 Solid 的可观察范围，因此当 props 更改时组件不会自动重新求值。</p><p>那么我们该如何解决我们的问题呢？</p><p>嗯，一般来说，我们需要在 Solid 可以观察到的地方访问 <code>props</code>。通常，这意味着在 JSX 内或在 <code>createMemo</code>、<code>createEffect</code> 或 thunk(<code>() =&gt; ...</code>) 内。这里有一种按照你的预期工作的解决方案：</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">BasicComponent</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#e36209\">props</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> {</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">return</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;{props.value </span><span style=\"color:#d73a49\">||</span><span style=\"color:#24292e\"> </span><span style=\"color:#032f62\">&quot;default&quot;</span><span style=\"color:#24292e\">}&lt;/</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">};</span></span>\n<span class=\"line\"></span></code></pre><p>这也可以等效地提升为一个函数：</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">BasicComponent</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#e36209\">props</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> {</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">value</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> () </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> props.value </span><span style=\"color:#d73a49\">||</span><span style=\"color:#24292e\"> </span><span style=\"color:#032f62\">&quot;default&quot;</span><span style=\"color:#24292e\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">return</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;{</span><span style=\"color:#6f42c1\">value</span><span style=\"color:#24292e\">()}&lt;/</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">};</span></span>\n<span class=\"line\"></span></code></pre><p>另一种方案，如果这是一个耗时计算的场景，那应该使用 <code>createMemo</code>。例如：</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">BasicComponent</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#e36209\">props</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> {</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">value</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">createMemo</span><span style=\"color:#24292e\">(() </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> props.value </span><span style=\"color:#d73a49\">||</span><span style=\"color:#24292e\"> </span><span style=\"color:#032f62\">&quot;default&quot;</span><span style=\"color:#24292e\">);</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">return</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;{</span><span style=\"color:#6f42c1\">value</span><span style=\"color:#24292e\">()}&lt;/</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">};</span></span>\n<span class=\"line\"></span></code></pre><p>或者使用工具函数</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">BasicComponent</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#e36209\">props</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> {</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  props </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">mergeProps</span><span style=\"color:#24292e\">({ value: </span><span style=\"color:#032f62\">&quot;default&quot;</span><span style=\"color:#24292e\"> }, props);</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">return</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;{props.value}&lt;/</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">};</span></span>\n<span class=\"line\"></span></code></pre><p>提醒一下，以下示例将 <em>不会</em> 工作：</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#6a737d\">// 错误示例</span></span>\n<span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">BasicComponent</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#e36209\">props</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> {</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> { </span><span style=\"color:#e36209\">value</span><span style=\"color:#24292e\">: </span><span style=\"color:#005cc5\">valueProp</span><span style=\"color:#24292e\"> } </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> props;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">value</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">createMemo</span><span style=\"color:#24292e\">(() </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> valueProp </span><span style=\"color:#d73a49\">||</span><span style=\"color:#24292e\"> </span><span style=\"color:#032f62\">&quot;default&quot;</span><span style=\"color:#24292e\">);</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">return</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;{</span><span style=\"color:#6f42c1\">value</span><span style=\"color:#24292e\">()}&lt;/</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">};</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6a737d\">// 错误示例</span></span>\n<span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">BasicComponent</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#e36209\">props</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> {</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">valueProp</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> prop.value;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">value</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">createMemo</span><span style=\"color:#24292e\">(() </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> valueProp </span><span style=\"color:#d73a49\">||</span><span style=\"color:#24292e\"> </span><span style=\"color:#032f62\">&quot;default&quot;</span><span style=\"color:#24292e\">);</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">return</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;{</span><span style=\"color:#6f42c1\">value</span><span style=\"color:#24292e\">()}&lt;/</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">};</span></span>\n<span class=\"line\"></span></code></pre><p>Solid 的组件是其性能的核心部分。Solid 所谓的 “消失” 组件是通过 prop 惰性求值实现的。而不是对 prop 表达式进行即时求值并传递，它推迟到了 child 中访问 prop 再执行。这样的话我们将执行推迟到最后一刻 —— 通常在 DOM 绑定，从而最大限度地提高性能。这么做不仅使层次结构扁平化而且消除了维护组件树的需要。</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#24292e\">&lt;</span><span style=\"color:#22863a\">Component</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">prop1</span><span style=\"color:#d73a49\">=</span><span style=\"color:#032f62\">&quot;static&quot;</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">prop2</span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\">{state.dynamic} /&gt;;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6a737d\">// 大致编译为：</span></span>\n<span class=\"line\"><span style=\"color:#6a737d\">// 我们取消跟踪组件主体来隔离它并避免更新消耗</span></span>\n<span class=\"line\"><span style=\"color:#6f42c1\">untrack</span><span style=\"color:#24292e\">(() </span><span style=\"color:#d73a49\">=&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#6f42c1\">Component</span><span style=\"color:#24292e\">({</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    prop1: </span><span style=\"color:#032f62\">&quot;static&quot;</span><span style=\"color:#24292e\">,</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    </span><span style=\"color:#6a737d\">// 动态表达式，所以我们将其包裹在一个 getter 中</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    </span><span style=\"color:#d73a49\">get</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">prop2</span><span style=\"color:#24292e\">() {</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">      </span><span style=\"color:#d73a49\">return</span><span style=\"color:#24292e\"> state.dynamic;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    }</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  })</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">);</span></span>\n<span class=\"line\"></span></code></pre><p>为了帮助保持响应性，Solid 有几个工具函数：</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#6a737d\">// 默认 props</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">props </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">mergeProps</span><span style=\"color:#24292e\">({ name: </span><span style=\"color:#032f62\">&quot;Smith&quot;</span><span style=\"color:#24292e\"> }, props);</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6a737d\">// 克隆 props</span></span>\n<span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">newProps</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">mergeProps</span><span style=\"color:#24292e\">(props);</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6a737d\">// 合并 props</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">props </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">mergeProps</span><span style=\"color:#24292e\">(props, otherProps);</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6a737d\">// 将 props 拆分为多个 props 对象</span></span>\n<span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> [</span><span style=\"color:#005cc5\">local</span><span style=\"color:#24292e\">, </span><span style=\"color:#005cc5\">others</span><span style=\"color:#24292e\">] </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">splitProps</span><span style=\"color:#24292e\">(props, [</span><span style=\"color:#032f62\">&quot;className&quot;</span><span style=\"color:#24292e\">])</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">&lt;</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\"> {</span><span style=\"color:#d73a49\">...</span><span style=\"color:#24292e\">others} </span><span style=\"color:#005cc5\">className</span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\">{</span><span style=\"color:#6f42c1\">cx</span><span style=\"color:#24292e\">(local.className, theme.component)} /&gt;</span></span>\n<span class=\"line\"></span></code></pre><h2 id=\"children\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#children\">#</a> Children</h2><p>Solid 处理 JSX Children 的方式类似 React。单个 child 是 <code>props.children</code> 上的单个值，多个 child 是通过值成员数组处理的。通常，你将 child 传递给 JSX 视图。但是，如果你想与它们交互，建议使用 <code>children</code> 工具函数，它能够解析任何下游流程控制并返回 Memo。</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#6a737d\">// 单个子节点</span></span>\n<span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">Label</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> (</span><span style=\"color:#e36209\">props</span><span style=\"color:#24292e\">) </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">class</span><span style=\"color:#d73a49\">=</span><span style=\"color:#032f62\">&quot;label&quot;</span><span style=\"color:#24292e\">&gt;Hi, { props.children }&lt;/</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#24292e\">&lt;</span><span style=\"color:#22863a\">Label</span><span style=\"color:#24292e\">&gt;&lt;</span><span style=\"color:#22863a\">span</span><span style=\"color:#24292e\">&gt;Josie&lt;/</span><span style=\"color:#22863a\">span</span><span style=\"color:#24292e\">&gt;&lt;/</span><span style=\"color:#22863a\">Label</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6a737d\">// 多个子节点</span></span>\n<span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">List</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> (</span><span style=\"color:#e36209\">props</span><span style=\"color:#24292e\">) </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;{props.children}&lt;/</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#24292e\">&lt;</span><span style=\"color:#22863a\">List</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  &lt;</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;First&lt;/</span><span style=\"color:#22863a\">div</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  {state.expression}</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  &lt;</span><span style=\"color:#22863a\">Label</span><span style=\"color:#24292e\">&gt;Judith&lt;/</span><span style=\"color:#22863a\">Label</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">&lt;/</span><span style=\"color:#22863a\">List</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6a737d\">// 映射子节点</span></span>\n<span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">List</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> (</span><span style=\"color:#e36209\">props</span><span style=\"color:#24292e\">) </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">ul</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  &lt;</span><span style=\"color:#22863a\">For</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">each</span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\">{props.children}&gt;{</span><span style=\"color:#e36209\">item</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">li</span><span style=\"color:#24292e\">&gt;{item}&lt;/</span><span style=\"color:#22863a\">li</span><span style=\"color:#24292e\">&gt;}&lt;/</span><span style=\"color:#22863a\">For</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">&lt;/</span><span style=\"color:#22863a\">ul</span><span style=\"color:#24292e\">&gt;;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6a737d\">// 使用工具函数修改和映射子项</span></span>\n<span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">List</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> (</span><span style=\"color:#e36209\">props</span><span style=\"color:#24292e\">) </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> {</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#6a737d\">// children 工具函数缓存值并处理所有中间反应性</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">memo</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">children</span><span style=\"color:#24292e\">(() </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> props.children);</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#6f42c1\">createEffect</span><span style=\"color:#24292e\">(() </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> {</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    </span><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">children</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">memo</span><span style=\"color:#24292e\">();</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    children.</span><span style=\"color:#6f42c1\">forEach</span><span style=\"color:#24292e\">((</span><span style=\"color:#e36209\">c</span><span style=\"color:#24292e\">) </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> c.classList.</span><span style=\"color:#6f42c1\">add</span><span style=\"color:#24292e\">(</span><span style=\"color:#032f62\">&quot;list-child&quot;</span><span style=\"color:#24292e\">))</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  })</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">return</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">ul</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    &lt;</span><span style=\"color:#22863a\">For</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">each</span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\">{</span><span style=\"color:#6f42c1\">memo</span><span style=\"color:#24292e\">()}&gt;{</span><span style=\"color:#e36209\">item</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">li</span><span style=\"color:#24292e\">&gt;{item}&lt;/</span><span style=\"color:#22863a\">li</span><span style=\"color:#24292e\">&gt;}&lt;/</span><span style=\"color:#22863a\">For</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  &lt;/</span><span style=\"color:#22863a\">ul</span><span style=\"color:#24292e\">&gt;;</span></span>\n<span class=\"line\"></span></code></pre><p><strong>重要：</strong> Solid 将 child 标签视为耗性能的表达式，并用与动态响应式表达式相同的方式包装它们。这意味着他们利用访问 <code>prop</code> 进行了惰性求值。在视图中使用它们之前，请小心避免多次访问它们或者进行解构。这是因为 Solid 没有大费周章地提前创建虚拟 DOM 节点然后对它们进行 diff 操作，所以这些 <code>props</code> 的解析必须是惰性且经过斟酌的。如果你希望这样做，请使用 <code>children</code> 工具函数，因为 <code>children</code> 会缓存这些值。</p></section><section class=\"mt-10\"><h1 id=\"ssr\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#ssr\">#</a> SSR</h1><p>Solid 通过将 JSX 模板编译为无比高效的字符串附加代码来处理服务器渲染。这可以通过传入 <code>generate: &quot;ssr&quot;</code> 到 babel 插件或者预设来实现。对于客户端和服务端而言，你都需要传入 <code>hydratable: true</code> 来生成注水兼容代码。</p><p>在 node 环境中运行时，<code>solid-js</code> 和 <code>solid-js/web</code> 运行时被置换为非响应式的对应。对于其他环境，你需要将导出条件设置为 <code>node</code> 来打包服务端代码。大多数构建工具都有办法做到这一点。一般来说，我们还是建议使用 <code>solid</code> 的导出条件，并建议库在<code>solid</code> 的导出条件下输出源代码。</p><p>构建 SSR 肯定需要更多配置，因为我们需要生成 2 个单独的包。客户端入口应该使用 <code>hydrate</code>：</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">import</span><span style=\"color:#24292e\"> { hydrate } </span><span style=\"color:#d73a49\">from</span><span style=\"color:#24292e\"> </span><span style=\"color:#032f62\">&quot;solid-js/web&quot;</span><span style=\"color:#24292e\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6f42c1\">hydrate</span><span style=\"color:#24292e\">(() </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">App</span><span style=\"color:#24292e\"> /&gt;, document);</span></span>\n<span class=\"line\"></span></code></pre><p><em>注意：可以从文档根节点进行渲染和注水。这允许我们在 JSX 中描述完整的视图。</em></p><p>服务器入口可以使用 Solid 提供的四个渲染函数之一。每个都会输出对应产物或者是一个要插入到文档头部的脚本标签。</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">import</span><span style=\"color:#24292e\"> {</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  renderToString,</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  renderToStringAsync,</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  renderToNodeStream,</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  renderToWebStream</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">} </span><span style=\"color:#d73a49\">from</span><span style=\"color:#24292e\"> </span><span style=\"color:#032f62\">&quot;solid-js/web&quot;</span><span style=\"color:#24292e\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6a737d\">// 同步字符串渲染</span></span>\n<span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">html</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">renderToString</span><span style=\"color:#24292e\">(() </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">App</span><span style=\"color:#24292e\"> /&gt;);</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6a737d\">// 异步字符串渲染</span></span>\n<span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">html</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">await</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">renderToStringAsync</span><span style=\"color:#24292e\">(() </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">App</span><span style=\"color:#24292e\"> /&gt;);</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6a737d\">// Node Stream API</span></span>\n<span class=\"line\"><span style=\"color:#6f42c1\">pipeToNodeWritable</span><span style=\"color:#24292e\">(App, res);</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#6a737d\">// Web Stream API (适用于 Cloudflare Workers)</span></span>\n<span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> { </span><span style=\"color:#005cc5\">readable</span><span style=\"color:#24292e\">, </span><span style=\"color:#005cc5\">writable</span><span style=\"color:#24292e\"> } </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">new</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">TransformStream</span><span style=\"color:#24292e\">();</span></span>\n<span class=\"line\"><span style=\"color:#6f42c1\">pipeToWritable</span><span style=\"color:#24292e\">(() </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#22863a\">App</span><span style=\"color:#24292e\"> /&gt;, writable);</span></span>\n<span class=\"line\"></span></code></pre><p>为方便起见，<code>solid-js/web</code> 导出了一个十分有用的 <code>isServer</code> 标志。这样大多数打包工具将能够在此标志下对任意代码进行的 treeshake 操作，或者仅在此标志下使用浏览器端之外的代码。</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">import</span><span style=\"color:#24292e\"> { isServer } </span><span style=\"color:#d73a49\">from</span><span style=\"color:#24292e\"> </span><span style=\"color:#032f62\">&quot;solid-js/web&quot;</span><span style=\"color:#24292e\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#d73a49\">if</span><span style=\"color:#24292e\"> (isServer) {</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#6a737d\">// 仅在服务端执行此操作</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">} </span><span style=\"color:#d73a49\">else</span><span style=\"color:#24292e\"> {</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#6a737d\">// 仅在浏览器上执行此操作</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">}</span></span>\n<span class=\"line\"></span></code></pre><h2 id=\"%E6%B3%A8%E6%B0%B4%E8%84%9A%E6%9C%AC\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#%E6%B3%A8%E6%B0%B4%E8%84%9A%E6%9C%AC\">#</a> 注水脚本</h2><p>甚至为了在 Solid 运行时加载之前渐进式注水，需要在页面上插入一个特殊的脚本。这个脚本可以通过 <code>generateHydrationScript</code> 生成和插入，也可以使用 <code>&lt;HydrationScript /&gt;</code> JSX 标签。</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">import</span><span style=\"color:#24292e\"> { generateHydrationScript } </span><span style=\"color:#d73a49\">from</span><span style=\"color:#24292e\"> </span><span style=\"color:#032f62\">&quot;solid-js/web&quot;</span><span style=\"color:#24292e\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">app</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">renderToString</span><span style=\"color:#24292e\">(() </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> &lt;</span><span style=\"color:#e36209\">App</span><span style=\"color:#24292e\"> /&gt;);</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">html</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> </span><span style=\"color:#032f62\">`</span></span>\n<span class=\"line\"><span style=\"color:#032f62\">  &lt;html lang=&quot;en&quot;&gt;</span></span>\n<span class=\"line\"><span style=\"color:#032f62\">    &lt;head&gt;</span></span>\n<span class=\"line\"><span style=\"color:#032f62\">      &lt;title&gt;🔥 Solid SSR 🔥&lt;/title&gt;</span></span>\n<span class=\"line\"><span style=\"color:#032f62\">      &lt;meta charset=&quot;UTF-8&quot; /&gt;</span></span>\n<span class=\"line\"><span style=\"color:#032f62\">      &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;</span></span>\n<span class=\"line\"><span style=\"color:#032f62\">      &lt;link rel=&quot;stylesheet&quot; href=&quot;/styles.css&quot; /&gt;</span></span>\n<span class=\"line\"><span style=\"color:#032f62\">      ${</span><span style=\"color:#6f42c1\">generateHydrationScript</span><span style=\"color:#032f62\">()</span><span style=\"color:#032f62\">}</span></span>\n<span class=\"line\"><span style=\"color:#032f62\">    &lt;/head&gt;</span></span>\n<span class=\"line\"><span style=\"color:#032f62\">    &lt;body&gt;${</span><span style=\"color:#24292e\">app</span><span style=\"color:#032f62\">}&lt;/body&gt;</span></span>\n<span class=\"line\"><span style=\"color:#032f62\">  &lt;/html&gt;</span></span>\n<span class=\"line\"><span style=\"color:#032f62\">`</span><span style=\"color:#24292e\">;</span></span>\n<span class=\"line\"></span></code></pre><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#d73a49\">import</span><span style=\"color:#24292e\"> { HydrationScript } </span><span style=\"color:#d73a49\">from</span><span style=\"color:#24292e\"> </span><span style=\"color:#032f62\">&quot;solid-js/web&quot;</span><span style=\"color:#24292e\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#d73a49\">const</span><span style=\"color:#24292e\"> </span><span style=\"color:#6f42c1\">App</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\"> () </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> {</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  </span><span style=\"color:#d73a49\">return</span><span style=\"color:#24292e\"> (</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    &lt;</span><span style=\"color:#22863a\">html</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">lang</span><span style=\"color:#d73a49\">=</span><span style=\"color:#032f62\">&quot;en&quot;</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">      &lt;</span><span style=\"color:#22863a\">head</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">        &lt;</span><span style=\"color:#22863a\">title</span><span style=\"color:#24292e\">&gt;🔥 Solid SSR 🔥&lt;/</span><span style=\"color:#22863a\">title</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">        &lt;</span><span style=\"color:#22863a\">meta</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">charset</span><span style=\"color:#d73a49\">=</span><span style=\"color:#032f62\">&quot;UTF-8&quot;</span><span style=\"color:#24292e\"> /&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">        &lt;</span><span style=\"color:#22863a\">meta</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">name</span><span style=\"color:#d73a49\">=</span><span style=\"color:#032f62\">&quot;viewport&quot;</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">content</span><span style=\"color:#d73a49\">=</span><span style=\"color:#032f62\">&quot;width=device-width, initial-scale=1.0&quot;</span><span style=\"color:#24292e\"> /&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">        &lt;</span><span style=\"color:#22863a\">link</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">rel</span><span style=\"color:#d73a49\">=</span><span style=\"color:#032f62\">&quot;stylesheet&quot;</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">href</span><span style=\"color:#d73a49\">=</span><span style=\"color:#032f62\">&quot;/styles.css&quot;</span><span style=\"color:#24292e\"> /&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">        &lt;</span><span style=\"color:#22863a\">HydrationScript</span><span style=\"color:#24292e\"> /&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">      &lt;/</span><span style=\"color:#22863a\">head</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">      &lt;</span><span style=\"color:#22863a\">body</span><span style=\"color:#24292e\">&gt;{</span><span style=\"color:#6a737d\">/*... App 其他部分*/</span><span style=\"color:#24292e\">}&lt;/</span><span style=\"color:#22863a\">body</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    &lt;/</span><span style=\"color:#22863a\">html</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  );</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">};</span></span>\n<span class=\"line\"></span></code></pre><p>当从文档中插入客户端不可用的资源来进行注水时，就会把事情搞砸。Solid 提供了一个 <code>&lt;NoHydration&gt;</code> 组件，其子组件可以在服务器上正常工作，但不会在浏览器中注水。</p><pre class=\"shiki\" style=\"background-color:#fff\"><code><span class=\"line\"><span style=\"color:#24292e\">&lt;</span><span style=\"color:#22863a\">NoHydration</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  {manifest.</span><span style=\"color:#6f42c1\">map</span><span style=\"color:#24292e\">(</span><span style=\"color:#e36209\">m</span><span style=\"color:#24292e\"> </span><span style=\"color:#d73a49\">=&gt;</span><span style=\"color:#24292e\"> (</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">    &lt;</span><span style=\"color:#22863a\">link</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">rel</span><span style=\"color:#d73a49\">=</span><span style=\"color:#032f62\">&quot;modulepreload&quot;</span><span style=\"color:#24292e\"> </span><span style=\"color:#005cc5\">href</span><span style=\"color:#d73a49\">=</span><span style=\"color:#24292e\">{m.href} /&gt;</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">  ))}</span></span>\n<span class=\"line\"><span style=\"color:#24292e\">&lt;/</span><span style=\"color:#22863a\">NoHydration</span><span style=\"color:#24292e\">&gt;</span></span>\n<span class=\"line\"></span></code></pre><h2 id=\"%E5%BC%82%E6%AD%A5%E5%92%8C%E6%B5%81%E5%BC%8F-ssr\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#%E5%BC%82%E6%AD%A5%E5%92%8C%E6%B5%81%E5%BC%8F-ssr\">#</a> 异步和流式 SSR</h2><p>异步和流式服务端渲染机制建立在 Solid 对应用如何工作的了解之上。它通过在服务器上使用 Suspense 和 Resource API 来实现，而不是提前获取然后渲染。Solid 获取资源数据在服务器上行为，就像在客户端上一样。代码的编写方式和执行模式完全相同。</p><p>异步渲染会等到所有 Suspense 边界解析后发送结果（或在静态站点生成的情况下将它们写入文件）。</p><p>一旦服务器将流同步地将内容刷新到浏览器，那么浏览器会即时展示你的 Suspense 回退。然后当异步数据在服务器上完成时，它通过相同的流将数据发送到客户端以完成 Suspense，浏览器完成工作并用真实内容替换回退。</p><p>这种方法的优点：</p><ul> <li>服务器不必等待异步数据响应。资源可以更快地开始在浏览器中加载，并且用户能够更快地看到内容。</li> <li>与 JAMStack 之类的客户端获取方案相比，这种方案的数据加载在服务器上即时开始，无需等待客户端 JavaScript 进行加载。</li> <li>所有数据都被序列化并自动从服务器传输到客户端。</li> </ul><h2 id=\"ssr-%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#ssr-%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9\">#</a> SSR 注意事项</h2><p>Solid 的 SSR 同构解决方案非常强大，因为你可以将代码编写一份代码就差不多可以在在两种环境中运行。然而，有人期望这会增加注水功能。大多数情况下，客户端中渲染的视图与服务器上渲染的视图大体相同。精确到文本可能不同，但在结构上标记应该是相同的。</p><p>我们使用在服务端中渲染的标记来匹配客户端的元素和资源位置。为此，客户端和服务器应该具有相同的组件。鉴于 Solid 在客户端和服务器上以相同的方式渲染，这根本不是问题。但是目前没有办法在服务器上渲染不会在客户端注水的东西。也没有办法对整个页面进行部分注水，也无法为其生成注水标记。要么全有要么全无。部分注水是我们未来想要探索的东西。</p><p>最后，所有资源都需要在 <code>render</code> 树下定义。它们会自动序列化并在浏览器中提取，这样起作用是因为 <code>render</code> 或 <code>pipeTo</code> 方法会跟踪渲染的进度。如果它们是在独立的上下文中创建的，我们就无法做到跟踪。同理可得，服务器上没有响应性，因此不要在初始渲染时更新 signal，并期望它们传递到树的上层。虽然我们有 Suspense 边界，但 Solid 的 SSR 基本是自上而下的。</p><h2 id=\"ssr-%E5%85%A5%E9%97%A8\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#ssr-%E5%85%A5%E9%97%A8\">#</a> SSR 入门</h2><p>SSR 配置很棘手。我们准备了几个示例包 <a href=\"https://github.com/solidjs/solid/blob/main/packages/solid-ssr\">solid-ssr</a> 。与此同时，一个新的脚手架工具正在开发中 <a href=\"https://github.com/solidjs/solid-start\">SolidStart</a> 旨在使开发更加流畅。</p><h2 id=\"%E9%9D%99%E6%80%81%E7%AB%99%E7%82%B9%E7%94%9F%E6%88%90%E5%85%A5%E9%97%A8\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#%E9%9D%99%E6%80%81%E7%AB%99%E7%82%B9%E7%94%9F%E6%88%90%E5%85%A5%E9%97%A8\">#</a> 静态站点生成入门</h2><p><a href=\"https://github.com/solidjs/solid/blob/main/packages/solid-ssr\">solid-ssr</a> 还附带一个用于生成静态或预渲染站点实用工具。阅读 README 文件了解更多信息。</p></section>";
var guide = {
	sections: sections,
	content: content
};

export { content, guide as default, sections };
