SolidJS:对于子组件不渲染列表

abc*_*abc 4 solid-js

我有一个父组件返回:

<List list={list()}>
    {(item, index) => <div>{item}</div>}
</List>
Run Code Online (Sandbox Code Playgroud)

其中list是创建的信号。List是我返回的自定义组件:

<div>
    <For each={list}>{children}</For>
</div>
Run Code Online (Sandbox Code Playgroud)

但每当list更新时,它都不会呈现。当我将For代码移至父组件时,它会进行渲染,那么将信号的值传递给子组件以使其在更新时不会重新渲染又是什么呢?

编辑:演示

import { render } from "solid-js/web";
import { createSignal, For } from "solid-js";

function Counter() {
  const [list, setList] = createSignal([]);
  const increment = () => setList([...list(), 1]);

  return (
    <>
      <button type="button" onClick={increment}>
        add
      </button>
      <p>broken list</p>
      <List list={list()} />

      <p>other list</p>
      <For each={list()}>
        {(item) => <p>{item}</p>}
      </For>
    </>
  );
}

function List({list}) {
  return (
    <For each={list}>
      {(item) => <p>{item}</p>}
    </For>
  );
}

render(() => <Counter />, document.getElementById("app"));
Run Code Online (Sandbox Code Playgroud)

编辑2:我本想使用<List list={list()} />,这也不起作用,但我之前错过了。

art*_*tem 9

它不起作用,因为propsSolid 中的解构会失去反应性,也就是说,所有解构的 props 值都不会更新。

解构props有时很方便,并且在其他框架中常用,但在 Solid 中并不真正推荐 -常见问题解答说:

通过解构,您可以将值与对象分离,从而为您提供该时间点的值并失去反应性。

您需要重写组件以在 JSX 中List使用单个props参数和访问:props.list

function List(props) {
  return (
    <For each={props.list}>
      {(item) => <p>{item}</p>}
    </For>
  );
}
Run Code Online (Sandbox Code Playgroud)

为什么解构不起作用?在 Solid 中,props是一个由 Solid 在幕后创建的对象,具有用于拦截对每个单独属性的访问的 getter,例如props.something. 需要跟踪 JSX(表达式和片段)和效果(由 创建createEffect()),以便在props.something更改时重新评估和更新它们。无法跟踪对解构属性的访问(当然有一个插件,但它不在核心框架中,因为它有一些开销)。