Попробуйте использовать что-то вроде уникального идентификатора вместо index
в качестве key
для каждого NotesListItem
в NotesList
. Смотрите этот связанный вопрос (может быть, дубликат на самом деле):
import React, { Component } from 'react';
import NotesListItem from './NotesListItem';
class NotesList extends Component {
constructor(props) {
super(props);
}
render() {
return (
<ul className="notes-list">
{this.props.notes.map((n, index) => <NotesListItem key={n.id} note={n} deleteNote={this.props.deleteNote} />)}
</ul>
);
}
}
export default NotesList;
Вы можете использовать что-то вроде uuid для генерации "уникального" идентификатора. Существует множество способов создания уникального ключа, но это зависит от вашей структуры данных. Кроме того, использование уникального идентификатора и фильтрация на основе идентификатора могут помочь избежать ситуации, когда два примечания в массиве имеют одинаковый текст, поскольку фильтрация на основе значения text
удалит их обоих.
import uuidv1 from 'uuid/v1';
// ...
handleSubmit(e) {
e.preventDefault();
if (this.input.value.length === 0) { return; }
this.state.notes.push({id: uuidv1(), text: this.input.value});
this.setState({ notes: this.state.notes });
this.input.value = "";
}
Я только предлагаю использовать что-то подобное, поскольку возможно, что ваш текст может быть продублирован. Возможно, вы даже можете использовать что-то вроде:
{this.props.notes.map((n, index) => <NotesListItem key={index + n.text} note={n} deleteNote={this.props.deleteNote} />)}
Кроме того, вы не должны напрямую изменять состояние, как this.state.notes.push({text: this.input.value});
. Попробуйте что-то вроде этого:
handleSubmit(e) {
e.preventDefault();
if (this.input.value.length === 0) { return; }
const note = { id: uuidv1(), text: this.input.value };
const notes = [...this.state.notes, note];
this.setState({ notes });
this.input.value = "";
}
Кроме того, я бы не использовал ref
для обработки контролируемых входов, особенно для установки значения. Почему бы не создать свойство для состояния, которое обрабатывает значение ввода в сочетании с простым обработчиком событий onChange
. Это будет соответствовать документации React Forms и «стандартному» способу обработки обновлений входных значений React:
handleChange(e) {
this.setState({ text: e.target.value });
}
handleSubmit(e) {
e.preventDefault();
if (this.state.text.length === 0) { return; }
const note = { id: uuidv1(), text: this.state.text };
const notes = [...this.state.notes, note];
this.setState({ text: '', notes });
}
render() {
// ...
<input type="text" className="new-note-input" value={this.state.text} onChange={this.handleChange} />
// ...
}
Вот пример в действии.
Другого ответа может быть достаточно для решения вашей проблемы. Я бы рекомендовал ознакомиться со следующей статьей , упомянутой / связанной в документации React Keys , в которой обсуждаются потенциальные негативные последствия использования индекса в качестве ключа.
Надеюсь, это поможет!