DEV Community

Discussion on: React lists without .map

Collapse
 
vladislavmurashchenko profile image
VladislavMurashchenko • Edited

In general, doing something like this is quite bold. I respect you for it.

But there are quite many disadvantages in this approach. There are some:

Props like item and index are passed to components implicitly. I personally prefer when everything is explicit. Also in most cases we don't need index and this index can cause unnecessary updates in some cases (for example inserting item to the middle). It can be fixed by get rid of cloning react elements and using render functions.

Also, this cloning React elements with spread operator is quite going too deep into react internal implementation. It would be better to use clone element

I noticed, that getKey relay on references of objects. That means that when reference changes, then key also changes. When key changes, component will be unmounted and mounted again. So it would be better just to have keyFn as required argument.

Repeat can be used only with react elements which doesn't have children inside them.

The last example with so many mutations inside looks really dangerous

Collapse
 
miketalbot profile image
Mike Talbot ⭐

Sure, I get your concerns.

A short rebuttal:

  • Repeat can be used on items with inner components, children is just another prop and it works fine

  • Index, sure can go any way on this, I mostly use this on lists that allow sorting, and the sortable HOC requires index so I just leave it in there. You could easily make it work differently by having explicit props for sure.

  • getKey is just a default implementation that works for object items that don't change, you can supply another keyFn and in my main app this would always be v=>v.id || v._id - but this is of course implementation specific.

Collapse
 
vladislavmurashchenko profile image
VladislavMurashchenko • Edited

About children I just mean, that it is not possible to do something like this:

{items.map(item => (
  <div key={item.name}>
      <span>{item.name}</span>
      <span>{item.age}</span>
  </div>
))}
Enter fullscreen mode Exit fullscreen mode

Because with Repeat we don't have access to item itself. All item based rendering always have to be inside a component and external children of the component must not rely on the item.

In some cases we just don't need a component

Thread Thread
 
miketalbot profile image
Mike Talbot ⭐

Right, right sorry. I should have though that through :)

Yeah you can't do that, unless you use a version which takes a function as a child, but then if it's this case... well I'd just probably do the items.map as you point out. My project's version does have support for a function child but really the semantics are then using { } so I don't bother and just use the map.

The real point was when you need to do a sub component because you need hooks in the wrapper. I'd prefer this laid out in the template version (because frequently in our code base we'd swap from <Repeat> to <VirtualRepeat> which has the same signature, but virtualises the elements.