There are some cases where you want to render a list of entities whose keys and values may change. If you have a table source Array<Item>
, and want to assign a component for each item id without re-creating the component when the item or index changes, you'd map it to a new table of type Map<string, Item>
like so:
local itemsById = derive(function()
local map: Map<string, Item> = {}
for _, item in items do
map[item.id] = item
end
return map
end)
return indexes(itemsById, function(item: () -> Item, id: string)
-- ...
end)
This approach works fine, but you lose the original order of the item in the process. It's tedious to keep this in mind when rendering lists where both keys and values change over time.
Storing an array of sources and using vide.values
instead is also an alternative, but it is not the best option in some cases, especially when using a separate library for state management.
Proposal
I think Vide could have a new table source API, vide.entries()
, with an additional argument for assigning a unique identifier to an entity. This way, both the key and value passed to transform
are sources, allowing the component to react to any change in order and state without being re-created.
return entries(items, function(item: Item, index: number)
return item.id
end, function(item: () -> Item, index: () -> number, id: string)
-- ...
end)
This is similar to the key
prop from React, which allows you to render components with the latest item index and value for as long as their key
prop stays the same. Components are only unmounted when the data associated with that specific key
is removed from the table.