SolidJS: в дочернем компоненте нет списка рендеринга

У меня есть родительский компонент, возвращающий:

      <List list={list()}>
    {(item, index) => <div>{item}</div>}
</List>

где - созданный сигнал. Listэто пользовательский компонент, который я сделал возвращающим:

      <div>
    <For each={list}>{children}</For>
</div>

но всякий раз 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"));

РЕДАКТИРОВАТЬ 2: я хотел использовать <List list={list()} />, который тоже не работает, но я пропустил его раньше.

1 ответ

Это не работает, потому что деструктуризация в Solid теряет реактивность, то есть все значения деструктурированных пропсов никогда не обновляются.

Деструктуризация иногда удобна и обычно используется в других фреймворках, но не рекомендуется в Solid — в FAQ сказано:

Деструктурируя, вы отделяете ценность от объекта, давая вам ценность в этот момент времени и теряя реактивность.

Вам нужно переписать Listкомпонент для использования одного параметра и доступа props.listв JSX:

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

Почему деструктуризация не работает? В твердом, props— это объект, созданный Solid за кулисами, с геттерами для перехвата доступа к каждому отдельному свойству, например . Нужно отслеживать JSX (выражения и фрагменты) и эффекты (созданные createEffect()), чтобы они переоценивались и обновлялись при props.somethingизменения. Невозможно отследить доступ к свойствам, которые деструктурированы (ну, для этого есть плагин , но он не входит в базовую структуру, потому что у него есть некоторые накладные расходы).

Другие вопросы по тегам