0

I am new to react and exploring different ways of creating a simple todo app. I am current getting the error "Warning: Each child in a list should have a unique "key" prop." Everything seems to be working okay however I must be doing something wrong.

class App extends Component {

  constructor(props) {
    super(props)

    this.state={
      list: [],
      item:{
        body: '',
        id: ''
      }
    }
  }

  handleInput(e) {
    this.setState ({
      item:{
        body: e.target.value,
        key: Date.now()
      }
    })
  }

  addItem(e) {
    e.preventDefault();
    const newItem = this.state.item
    const list = [...this.state.list]
    list.push(newItem)
    console.log(list)
    this.setState ({
      list,
      item:{
        body: '',
        id: ''
      }
    })
  }

  render() {
    return (
      <div className="App">
        <h1>To Do List</h1>
        <form>
          <input
          type='text'
          placeholder='enter a new Todo'
          value={this.state.item.body}
          onChange={this.handleInput.bind(this)}
          >
          
          </input>
          <button onClick={this.addItem.bind(this)}>
            submit
          </button>
        </form>
        <br/>
        
          {this.state.list.map(item => {
            return (
              <li>{item.body}</li>
            
            )
          })}
        
      </div>
    );
  }
}

export default App;

If anyone could help that would br great/explaing why this error is happening that would be great.

TheMayerof
  • 183
  • 2
  • 4
  • 15

5 Answers5

0

Short answer: give your <li>{item.body}</li> a unique key. Like <li key={item.id}>{item.body}</li>

Also check you handleInput. Did you mean id: Date.now()?

  handleInput(e) {
    this.setState ({
      item:{
        body: e.target.value,
        key: Date.now() // <--- id: Date.now()
      }
    })
  }

Explanation: See https://stackoverflow.com/a/43892905

LeoYulinLi
  • 129
  • 6
0

You should give each row a specific id which is unique. You can also use index beside item in arrow function if you are not sure the id is unique, like this code:

{ this.state.list.map((item, index) => {
  return (
    <li key={index}>{item.body}</li>
  )
}))}
Mostafa
  • 1
  • 1
  • 2
0

To give a unique identity to every element inside the array, a key is required. Keys help React identify which items have changed (added/removed/re-ordered).

i.e.

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li key={number.toString()}>
    {number}
  </li>
);

Please bear in mind that react will run into performance degradation and unexpected behaviour if unstable keys are used.

Take a quick look at the official documentation for more illustration: https://reactjs.org/docs/lists-and-keys.html

Amr
  • 646
  • 1
  • 6
  • 21
0

So I just realised it was a typo, my "key" value in the handleInput method was incorrectly named.

TheMayerof
  • 183
  • 2
  • 4
  • 15
0

I was getting this error when using react-bootstrap's Accordion component, it makes no use of <ul> or <li> tags, so it had me very confused.

If it helps anyone, a way to debug this is to add a key={0} or something like that to every component and tag. Eventually, the warning will change and you'll be able to pinpoint where the problem resides.

  • This does not really answer the question. If you have a different question, you can ask it by clicking [Ask Question](https://stackoverflow.com/questions/ask). To get notified when this question gets new answers, you can [follow this question](https://meta.stackexchange.com/q/345661). Once you have enough [reputation](https://stackoverflow.com/help/whats-reputation), you can also [add a bounty](https://stackoverflow.com/help/privileges/set-bounties) to draw more attention to this question. - [From Review](/review/late-answers/31305681) – pensum Mar 19 '22 at 01:41