如何使用React + Firebase编辑数据库中的文档信息?无法在尚未安装的组件上调用setState

时间:2019-01-06 14:02:31

标签: javascript reactjs firebase firebase-realtime-database

我在我的项目中使用react和firebase。首先,我呈现了一些用户信息,但随后我想通过单击“编辑”来编辑它,但我得到了错误:

  

无法在尚未安装的组件上调用setState。这是一个   无操作,但这可能表明您的应用程序中存在错误。代替,   直接分配给this.state或定义state = {};类   属性在EditBookComponentForm中具有所需状态   组件。

然后单击“编辑”按钮必须呈现EditBookComponentForm,并且输入raws的第一个值必须类似于数据库中的值。如何解决该错误?

import React, {Component} from 'react';
import firebase from '../firebase/firebase.js';
import AddBookComponentForm from '../addBookComponentForm/AddBookComponentForm'
import EditBookComponentForm from '../editBookComponentForm/EditBookComponentForm'


export default class BooksComponent extends Component{
  EditBookComponentForm = new EditBookComponentForm();
  constructor(props) {
    super(props)
    this.state = {
      books: null,
      status: false
    }
    this.getBook = this.getBook.bind(this);
  }
  componentDidMount() {
    this.getBook();
  }
  getBook =() =>{
    const newArray = [];
    const selfThis = this;
    console.log("i am working")
    const db = firebase.firestore();
    db.settings({
      timestampsInSnapshots: true
    });
    db.collection("LibraryDB").where("user", "==",
      firebase.auth().currentUser.uid)
      .get()
      .then(function(querySnapshot) {
          querySnapshot.forEach(function(doc) {
              console.log(doc.id, " => ", doc.data());
              let bookWithId = doc.data()
              bookWithId.id = doc.id
              newArray.push(bookWithId);
          });
          //console.log(newArray);
          selfThis.setState({
            books: newArray
          });
          console.log("My work has ended")
      })
      .catch(function(error) {
          console.log("Error getting documents: ", error);
      });
  };
  deleteBook = id => {
      const db = firebase.firestore();
      this.setState(prevState => ({
        books: prevState.books.filter(el => el.id !== id)
      }));
      db.collection("LibraryDB").doc(id).delete()
      .then(function() {
          console.log("Document successfully deleted!");
      }).catch(function(error) {
          console.error("Error removing document: ", error);
      });
    };

  editBook = (id,auth,name) =>{
    this.EditBookComponentForm.updateState(id,auth,name);
  };

  renderBooks(arr) {
    console.log("items",arr)
     return arr.map(book => {
       return (
           <tr key={book.id}>
               <td>
                 <p>{book.author}</p>
                 <p>{book.bookName}</p>
                 <button
                     onClick= {() => { this.editBook(book.id, book.author, book.bookName) }}>
                     Edit
                 </button>
                 <button
                   onClick={() => { this.deleteBook(book.id) }}>
                   Delete
                 </button>
               </td>
           </tr>
       );
     });
   }

  render(){
    if(!this.state.books){
      return <p>0000000</p>;
    }
    return(
      <div>
        <AddBookComponentForm updateBooksComponent={this.getBook} />
        {this.state.status ? <EditBookComponentForm/> : <null/>}
          <table>
            <tbody>
             <tr>
                 <th>Author </th>
                 <th>Book name</th>
             </tr>
                {this.renderBooks(this.state.books)}
             </tbody>
          </table>
      </div>
  )};
};

第二个文件:

import React, { Component }  from 'react';
import firebase from '../firebase/firebase.js';

export default class EditBookComponentForm extends Component{

  state = {
      bookName:'',
      author:'',
      id:''
  };
  updateState(id,auth,name){
    this.setState({
      bookName: name,
      author: auth,
      id: id
    })
  };


  onChangeInputBookName = (event) => {
    this.setState({bookName: event.target.value})
  };
  onChangeInputAuthor = (event) => {
    this.setState({author: event.target.value})
  };
  editBook = (id) =>{
     const db = firebase.firestore();
     db.collection("LibraryDB").doc(id).set({
       bookName: this.state.bookName,
       author: this.state.author
     })
     .then(function() {
       console.log("Document successfully written!");
     })
     .catch(function(error) {
       console.error("Error writing document: ", error);
     });
  };

render(){
  return(
    <div>
    <form className="null">
        <input type='text'
               value = {this.state.author}
               onChange ={ this.onChangeInputAuthor }/>
        <input type='text'
               value = {this.state.bookName}
               onChange ={ this.onChangeInputBookName }/>
        <button
            onClick={() => { this.editBook(this.state.id) }}>
            Edit
        </button>
    </form>
    </div>
  )} ;
};

2 个答案:

答案 0 :(得分:0)

因此,我不会从this.参考中克隆和更新状态,您应该将道具传递给<EditBookComponentForm {...desiredProps} />

例如:

  editBook = (id, auth, name) =>{
    this.setState({ bookprops: { bookName: id, author: auth, bookName: name } });
  };

 {this.state.status ? <EditBookComponentForm editProps={this.state.bookprops} /> : <null/>}

然后您可以在您的EditBookComponentForm组件中通过this.props.editProps

到达传递的道具。

这意味着可以在您的EditBookComponentForm中删除以下内容

updateState(id,auth,name){
    this.setState({
      bookName: name,
      author: auth,
      id: id
    })
  };

答案 1 :(得分:0)

该错误告诉您在EditBookComponentForm中最初设置状态之前,您曾尝试设置状态。因此,向该组件添加一个构造函数,并在其中设置状态,如下所示:

constructor() {
  this.state = {
    bookName:'',
    author:'',
    id:''
  };
}