{ "id": "df076802c4af9900216762b5", "source": "solid:signals", "type": "github-document", "title": "list-rendering", "content": "---\ntitle: List rendering\norder: 3\nuse_cases: \u003e-\n rendering arrays, dynamic lists, data iteration, tables, repeating elements,\n collection display, performance optimization\ntags:\n - lists\n - arrays\n - for\n - index\n - iteration\n - rendering\n - performance\nversion: '1.0'\ndescription: \u003e-\n Efficiently render dynamic lists in Solid using For and Index components.\n Optimize performance for different data scenarios.\n---\n\nList rendering allows you to generate multiple elements from a collection of data, such as an array or object, where each element corresponds to an item in the collection.\n\nWhen dealing with dynamic data, Solid offers two ways to render lists: the `\u003cFor\u003e` and `\u003cIndex\u003e` components.\nBoth of these components help you loop over data collections to generate elements, however, they both cater to different scenarios.\n\n## `\u003cFor\u003e`\n\n`\u003cFor\u003e` is a looping component that allows you to render elements based on the contents of an array or object.\nThis component is designed to be used with **complex data structures**, such as arrays of objects, where the order and length of the list may change frequently.\n\nThe sole property in `\u003cFor\u003e` is `each` , through which you can specify the data collection to loop over.\nThis property expects an array, however, it can also accept objects that have been converted to arrays using utilities such as [`Object.entries`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries) or [`Object.values`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values).\n\n```jsx\nimport { For } from \"solid-js\"\n\n\u003cFor each={data()}\u003e\n {(item, index) =\u003e\n // rendering logic for each element\n }\n\u003c/For\u003e\n```\n\nBetween the `\u003cFor\u003e` tags, the component requires a [callback function](https://developer.mozilla.org/en-US/docs/Glossary/Callback_function) which will dictate how each item in the data collection should be rendered.\nThis structure resembles the callback used within JavaScript's [`map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) method, providing a familiar pattern to follow.\n\nThe function receives two arguments:\n- `item`: represents the current item in the data collection that is being rendered over.\n- `index`: the current item's index within the collection.\n\nYou can access the current `item` and `index` to dynamically set attributes or content of the JSX elements.\nIndex is a [*signal*](/concepts/signals) and must be called as a function to retrieve its value.\n\n```jsx\n\u003cFor each={data()}\u003e\n\t{(item, index) =\u003e (\n\t\t\u003cli\n\t\t\tstyle={{\n\t\t\t\tcolor: index() % 2 === 0 ? \"red\" : \"blue\"\n\t\t\t}}\n\t\t\u003e\n\t\t\t{item.name}\n\t\t\u003c/li\u003e\n\t)}\n\u003c/For\u003e\n```\n\n## `Index`\n\n`\u003cIndex\u003e`, similar to `\u003cFor\u003e`, is a looping component that allows you to render elements based on the contents of an array or object.\nHowever, when the order and length of the list remain _stable_, but the content may change frequently, `\u003cIndex\u003e` is a better option because it results in fewer re-renders.\n\n```jsx\nimport { Index } from \"solid-js\"\n\n\u003cIndex each={data()}\u003e\n\t{(item, index) =\u003e (\n\t\t// rendering logic for each element\n\t)}\n\u003c/Index\u003e\n```\n\nSimilar to the `\u003cFor\u003e` component, `\u003cIndex\u003e` accepts a single property named `each`, which is where you pass the structure you wish to loop over.\n\nWhere the `index` is a signal with `\u003cFor\u003e`, it remains fixed with `\u003cIndex\u003e`.\nThis is because `\u003cIndex\u003e` is more concerned with the **index** of the elements in the array.\nBecause of this, the `item` is a signal, allowing the _content_ at each index to change without a re-render while the index remains fixed.\n\n```jsx\nimport { Index } from \"solid-js\"\n\n\u003cIndex each={data()}\u003e\n\t{(item, index) =\u003e (\n\t\t\u003cli\u003e\n\t\t\t{item().name} - {item().completed}\n\t\t\u003c/li\u003e\n\t)}\n\u003c/Index\u003e\n```\n\n## `\u003cIndex\u003e` vs `\u003cFor\u003e`\n\n`\u003cFor\u003e` is designed to be used when the *order* and *length* of the list may change frequently.\nWhen the list value changes in `\u003cFor\u003e`, the entire list is re-rendered.\nHowever, if the array undergoes a change, such as an element shifting position, `\u003cFor\u003e` will manage this by simply **moving** the corresponding DOM node and **updating** the index.\n\n`\u003cIndex\u003e`, however, is designed to be used when the **order** and **length** of the list remain _stable_, but the content may change frequently.\nWhen the list value changes in `\u003cIndex\u003e`, only the content at the specified index is updated.\n\n### When to use `\u003cFor\u003e`\n\nIn cases where signals, nested loops, or dynamic lists are not required, `\u003cFor\u003e` is the best option.\nFor example, when creating a list of static elements, such as a list of links, `\u003cFor\u003e` is the best option to use.\nThis is because it will only modify the indexes of the elements in the list, rather than re-rendering the entire list.\n\n```jsx\nimport { createSignal, For } from \"solid-js\"\n\nfunction StringList() {\n\tconst [items, setItems] = createSignal([\"Item 1\", \"Item 2\", \"Item 3\"])\n\n\treturn (\n\t\t\u003cul\u003e\n\t\t\t\u003cinput\n\t\t\t\ttype=\"text\"\n\t\t\t\tonInput={(e) =\u003e {\n\t\t\t\t\t// add the new item to the list\n\t\t\t\t}}\n\t\t\t/\u003e\n\t\t\t\u003cFor each={items()}\u003e\n\t\t\t\t{(item, index) =\u003e (\n\t\t\t\t\t\u003cli\u003e\n\t\t\t\t\t\t{item} - {index()}\n\t\t\t\t\t\u003c/li\u003e\n\t\t\t\t)}\n\t\t\t\u003c/For\u003e\n\t\t\u003c/ul\u003e\n\t)\n}\n```\n\nIf you are working with signals, [JavaScript primitives like strings and numbers](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) or input fields, `\u003cIndex\u003e` is the better option to use.\nIf you were using `\u003cFor\u003e`, the entire list would be re-rendered when a value changes, even if the length of the list remains unchanged.\n`\u003cIndex\u003e`, instead, will update the content at the specified index, while the rest of the list remains unchanged.\n\n```jsx\nimport { createSignal, Index } from \"solid-js\"\n\nfunction FormList() {\n\tconst [inputs, setInputs] = createSignal(['input1','input2','input3'])\n\treturn(\n\t\t\u003cform\u003e\n\t\t\t\u003cIndex each={inputs()}\u003e\n\t\t\t\t{(input, index) =\u003e (\n\t\t\t\t\t\u003cinput\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\tvalue={input()}\n\t\t\t\t\t\tonInput={(e) =\u003e {\n\t\t\t\t\t\t\t// update the input value\n\t\t\t\t\t\t}}\n\t\t\t\t\t/\u003e\n\t\t\t\t)}\n\t\t\t\u003c/Index\u003e\n\t\t\u003c/form\u003e\n\t)\n}\n```", "url": "https://github.com/solidjs/solid-docs/blob/HEAD/src/routes/concepts/control-flow/list-rendering.mdx", "metadata": { "path": "src/routes/concepts/control-flow/list-rendering.mdx", "repo": "solidjs/solid-docs", "repo_url": "https://github.com/solidjs/solid-docs.git", "size": 5981, "source_type": "github" }, "hash": "f413cc208b774c4bcbb0b0670dac9f19300337faf1a8dd8daa79fde54620b98d", "timestamp": "2026-02-23T11:43:00.186618758+01:00" }