在firebase更改显示时,反应this.setState不更新我的值

时间:2018-05-17 10:40:50

标签: javascript reactjs firebase firebase-realtime-database

我的代码有问题。我想在react + fireabse中做笔记。向fireabse works和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>
);

}

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

问题线:

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。 要解决此问题,您需要:

  1. 复制(deepclone)状态数组(你应该使用ImmutableJS,但这可以用于测试:const copiedArray = JSON.parse(JSON.stringify(array)))
  2. 对复制的数组copiedArray进行更改。
  3. setState('notes', copiedArray)
  4. 其他建议:

    我建议你做以下事情。将firebase图层与查看图层隔离。不建议将组件的责任与db通信混合。 你这样做之后。您将从组件外部传递注释列表。任何处理数据库的方法(在你的情况下,firebase也将作为一个参数。)

    // Notes Container
        const notes = FireBaseConnector.getNotes();
        const {
            add,
            edit,
            delete,
        } = FireBaseConnector
    
        <Notes notes={notes}
             onAdd={add}
             onEdit={edit}
             onRemove={delete}
        />
    

答案 1 :(得分:0)

你应该这样做:

const newNotes = [...this.state.notes]
const newNode = {
  id: snap.key,
  noteContent: snap.val().noteContent,
}
newNotes.push(newNode)
this.setState({
     notes: newNotes,
});

你不能只是推动你需要用新数组替换节点数组。需要遵循不变性来告诉回复