У меня проблема с кодом. Я пытаюсь делать заметки в react + fireabse. Добавление заметок в fireabse работает, и setState показывает их, но если я хочу изменить значение заметки, второй setState не меняет его, но в firebase заметка изменит свое значение.
Вот мой код
constructor() {
super();
this.app = firebase.initializeApp(DB_CONFIG);
this.database = this.app.database().ref().child('notes');
this.state = {
notes: [],
};
}
componentDidMount() {
this.database.on('child_added', snap => {
this.state.notes.push(new Note(snap.key, snap.val().noteContent));
this.setState({
notes: this.state.notes
});
});
this.database.on('child_changed', snap => {
this.state.notes.forEach(note => {
if (snap.key === note.id) {
note.id = snap.key;
note.noteContent = snap.val().noteContent;
}
});
this.setState({
notes: this.state.notes,
});
});
}
addNote(note) {
this.database.push().set({
noteContent: note,
});
}
changeNote(id, note) {
this.database.child(id).update({
noteContent: note,
});
}
render() {
return (
<div>
<div> {
this.state.notes.map(note => {
return (
<NoteComponent noteContent = {note.noteContent}
noteId = {note.id}
key = {note.id}
changeNote = {this.changeNote.bind(this)}>
</NoteComponent>
)
})
}
</div>
<div>
</div>
<NoteFormComponent
addNote = {this.addNote.bind(this)}>
</NoteFormComponent>
</div>
);
}
Спасибо за помощь.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Проблемные строки:
this.state.notes.push(new Note(snap.key, snap.val().noteContent));
или же
this.state.notes.forEach(note => {
if (snap.key === note.id) {
note.id = snap.key;
note.noteContent = snap.val().noteContent;
}
});
this.setState({
notes: this.state.notes,
});
Вы не можете изменить значение состояния таким образом. Вы ДОЛЖНЫ использовать setState.
Чтобы это исправить, вам необходимо:
const copiedArray = JSON.parse(JSON.stringify(array)))copiedArray.setState('notes', copiedArray)Другие предложения:
Я бы посоветовал вам сделать следующее. Изолируйте слой базы огня от слоя просмотра. Не рекомендуется совмещать обязанности компонента с связью с базой данных. После того, как вы это сделаете. вы передадите список примечаний извне компонента. И любой метод, работающий с базой данных (firebase в вашем случае также будет параметром).
// Notes Container
const notes = FireBaseConnector.getNotes();
const {
add,
edit,
delete,
} = FireBaseConnector
<Notes notes = {notes}
onAdd = {add}
onEdit = {edit}
onRemove = {delete}
/>
Вы должны сделать что-то вроде этого:
const newNotes = [...this.state.notes]
const newNode = {
id: snap.key,
noteContent: snap.val().noteContent,
}
newNotes.push(newNode)
this.setState({
notes: newNotes,
});
вы не можете просто нажать, вам нужно заменить массив узлов новым массивом. необходимо соблюдать неизменяемость, чтобы сказать, как реагировать на повторную визуализацию
Спасибо за ваш отзыв, но в вашем коде я добавляю новый элемент и хочу только изменить выбранный узел noteContent, как это происходит в firebase, но this.setState не изменяет noteContent, после обновления страницы данные будут загружены из firebase и будет выглядеть так, как хочет