1

Is there any chance to make this code DRY?

let allPosts = this.state.posts.map((item, i, arr) => {
  if (i === arr.length - 1) {
    return <Post
      key={item._id}
      post={item}
      nickname={this.props.nickname}
      ref={this.lastPostRef}
    /> 
  }

  return <Post
    key={item._id}
    post={item}
    nickname={this.props.nickname}
  />
});

The perfect solution would be

...
nickname={this.props.nickname}
if (i === arr.length - 1) {
  ref={this.lastPostRef}
} ...

but it doesn't work in React.

Andrew Korin
  • 294
  • 3
  • 17
  • 1
    `ref={(i === arr.length - 1) && this.lastPostRef}` should do it – Hamms Aug 04 '18 at 19:21
  • Possible duplicate of [React: inline conditionally pass prop to component](https://stackoverflow.com/questions/32232659/react-inline-conditionally-pass-prop-to-component) – Andy Ray Aug 04 '18 at 19:28

2 Answers2

3

There is a cleaner way to do this without any conditions:

let allPosts = this.state.posts.map((item, i, arr) => {
  return <Post
      key={item._id}
      post={item}
      nickname={this.props.nickname}
      ref={el => this.lastPostRef = el}
    /> 
});

On every iteration of the loop, the last post ref will be updated with the latest element. By the end of the map, the last post will be set the to last post ref. Magic!

Slava Knyazev
  • 5,377
  • 1
  • 22
  • 43
  • It's a real magic because I don't understand now why I am able to get the post with `this.lastPostRef` and `this.lastPostRef.current` doesn't work for me. But I really like this variant. – Andrew Korin Aug 04 '18 at 20:19
2

Why not just let the property be undefined?

 return <Post 
    key={item._id}
    post={item}
    nickname={this.props.nickname}
    ref={ i === arr.length - 1 ? this.lastPostRef : undefined }
 />
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151