reactjseslinthigh-order-component

How to set keys for HOC components?


class Demo extends Component {
  render() {
    const { list } = this.state
    return (
      <div>
        {list.map(this._renderItem)}
      </div>
    )
  }
  _renderItem = item => {
    const Item = withSwipeDelete(
      <div>{item.id}</div>,
      () => console.log('callback')
    )
    return <Item />
  }
}

It's an example for my code, which warning: Each child in a list should have a unique "key" prop.

So I tried:

  _renderItem = item => {
    const Item = withSwipeDelete(
      <div key={item.id}>{item.id}</div>, // add key here
      () => console.log('callback')
    )
    return <Item />
  }

And this:

  _renderItem = item => {
    const Item = withSwipeDelete(
      <div>{item.id}</div>,
      () => console.log('callback')
    )
    return <Item key={item.id} /> // add key here
  }

Both not work.

withSwipeDelete is a higher-order-components:

export default function withSwipeDelete(Cell, onDelete) {
  return class extends Component {
    render() {
      return (
        <div>
          {Cell}
        </div>
      )
    }
  }
}

Solution

  • The second solution that you have posted should be working:

    _renderItem = item => {
        const Item = withSwipeDelete(
          <div>{item.id}</div>,
          () => console.log('callback')
        )
        return <Item key={item.id} /> // add key here
    }
    

    I have tried it here https://codesandbox.io/s/brave-http-3w3ki

    As long as the id is unique, no error is present in the console.

    Explanation: React would require you to put a key in places, where you are trying too render an array of items. If we simplify your code (regardless of the HOC), you are actually rendering an array inside the <div> in the main render. That translated means that you have an array of <Item /> components (since this is what _renderItem would return), thus, you need a key for each of those <Item />.