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
изменения. Невозможно отследить доступ к свойствам, которые деструктурированы (ну, для этого есть плагин , но он не входит в базовую структуру, потому что у него есть некоторые накладные расходы).