Reputation: 1559
I have a parent component returning:
<List list={list()}>
{(item, index) => <div>{item}</div>}
</List>
where list
is a created signal. List
is a custom component I made returning:
<div>
<For each={list}>{children}</For>
</div>
but whenever list
is updated, it isn't rendered. When I move the For
code to the parent, it renders, so what is it about passing a signal's value to a child component that makes it not rerender on updates?
EDIT: demo
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"));
EDIT 2: I meant to use <List list={list()} />
, which also doesn't work, but I missed it earlier.
Upvotes: 4
Views: 3771
Reputation: 51729
It does not work because destructuring props
in Solid loses reactivity, that is, all the destructured props values do not update, ever.
Destructuring props
is sometimes convenient and commonly used in other frameworks, but is not really recommended in Solid - the FAQ says:
By destructuring, you separate the value from the object, giving you the value at that point in time and losing reactivity.
You need to rewrite List
component to use single props
parameter and access props.list
in the JSX:
function List(props) {
return (
<For each={props.list}>
{(item) => <p>{item}</p>}
</For>
);
}
Why destructuring does not work? In Solid, props
is an object, created behind the scenes by Solid, with getters for intercepting access to each individual property, like props.something
. It's needed to track JSX (expressions and fragments) and effects (created by createEffect()
) so that they are reevaluated and updated when props.something
changes. There's no way to track access to properties which are destructured (well there's plugin for that, but it's not in the core framework because it has some overhead).
Upvotes: 9