Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SolidJS: For in child component not rendering list

Tags:

solid-js

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.

like image 752
abc Avatar asked Sep 15 '25 13:09

abc


1 Answers

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).

like image 137
artem Avatar answered Sep 17 '25 18:09

artem



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!