簡體   English   中英

無法使用 function 在 React Context 中更新 state

[英]Can't update state in React Context using function

我目前有兩個上下文 - GalleryContext 和 AdminContext

在 AdminContext 中,每當我啟動 handleSendImage() 時,我都會嘗試從 GalleryContext 調用 function (getGallery()),它會更新 GalleryContext 中的圖庫 state。

但是,我收到此錯誤:Unhandled Rejection (TypeError): this.setState is not a function

誰能告訴我如何解決這個問題? 非常感謝提前!

這是我的代碼:

畫廊上下文:

class GalleryProvider extends Component {
  state = {
    gallery: []
  };
  getGallery() {
    let database = firebase
      .database()
      .ref("/gallery/")
      .once("value")
      .then(images => {
        console.log(images.val());
        this.setState(
          {
            gallery: images.val()
          },
          () => {}
        );
      });
  }
  componentDidMount() {
    this.getGallery();
  }
  render() {
    return (
      <GalleryContext.Provider
        value={{
          ...this.state,
          getGallery: this.getGallery
        }}>
        {this.props.children}
      </GalleryContext.Provider>
    );
  }
}

AdminContext.js

class AdminProvider extends Component {
  static contextType = GalleryContext;
  state = {
    upload_image: null,
    gallery_title: null,
    gallery_description: null,
    gallery_filename: null,
    progress: null
  };
  handleSendImage = (event, gallery, user) => {
    event.preventDefault();
    const { upload_image } = this.state;
    firebase
      .storage()
      .ref(`images/${upload_image.name}`)
      .put(upload_image)
      .on(
        "state_changed",
        snapshot => {
          // progrss function ....
          const progress = Math.round(
            (snapshot.bytesTransferred / snapshot.totalBytes) * 100
          );
          this.setState({
            progress
          });
        },
        error => {
          // error function ....
          console.log(error);
        },
        () => {
          // complete function ....
          firebase
            .storage()
            .ref("images")
            .child(upload_image.name)
            .getDownloadURL()
            .then(url => {
              const newImage = {
                description: this.state.gallery_description,
                download_url: url,
                file_name: this.state.gallery_filename,
                id: gallery.length,
                uploader_uid: user.uid
              };
              firebase
                .database()
                .ref("/gallery/")
                .child(gallery.length)
                .set(newImage)
                .then(() => {
                  this.context.getGallery();
                })
                .catch(error => {
                  console.log(error);
                });
            });
        }
      );
  };
  render() {
    return (
      <AdminContext.Provider
        value={{
          ...this.state
          handleSendImage: this.handleSendImage
        }}>
        {this.props.children}
      </AdminContext.Provider>
    );
  }
}

由於您使用的是狀態,因此 class 組件需要一個構造函數,並且需要在構造函數中綁定您的方法。 我建議你試試下面的代碼:

class AdminProvider extends Component {

  static contextType = GalleryContext;
  constructor(props) { 
  super(props)
  this.state = {
    upload_image: null,
    gallery_title: null,
    gallery_description: null,
    gallery_filename: null,
    progress: null
  };
  this.handleSendImage = this.handleSendImage.bind(this);
  }
  handleSendImage = (event, gallery, user) => {
    event.preventDefault();
    const { upload_image } = this.state;
    firebase
      .storage()
      .ref(`images/${upload_image.name}`)
      .put(upload_image)
      .on(
        "state_changed",
        snapshot => {
          // progrss function ....
          const progress = Math.round(
            (snapshot.bytesTransferred / snapshot.totalBytes) * 100
          );
          this.setState({
            progress
          });
        },
        error => {
          // error function ....
          console.log(error);
        },
        () => {
          // complete function ....
          firebase
            .storage()
            .ref("images")
            .child(upload_image.name)
            .getDownloadURL()
            .then(url => {
              const newImage = {
                description: this.state.gallery_description,
                download_url: url,
                file_name: this.state.gallery_filename,
                id: gallery.length,
                uploader_uid: user.uid
              };
              firebase
                .database()
                .ref("/gallery/")
                .child(gallery.length)
                .set(newImage)
                .then(() => {
                  this.context.getGallery();
                })
                .catch(error => {
                  console.log(error);
                });
            });
        }
      );
  };
  render() {
    return (
      <AdminContext.Provider
        value={{
          ...this.state
          handleSendImage: this.handleSendImage
        }}>
        {this.props.children}
      </AdminContext.Provider>
    );
  }
}

相似地:

    class GalleryProvider extends Component {
  constructor(props) { 
  super(props);
  this.state = {
    gallery: []
  };
  this.getGallery = this.getGallery.bind(this);
  }
  getGallery() {
    let database = firebase
      .database()
      .ref("/gallery/")
      .once("value")
      .then(images => {
        console.log(images.val());
        this.setState(
          {
            gallery: images.val()
          },
          () => {}
        );
      });
  }
  componentDidMount() {
    this.getGallery();
  }
  render() {
    return (
      <GalleryContext.Provider
        value={{
          ...this.state,
          getGallery: this.getGallery
        }}>
        {this.props.children}
      </GalleryContext.Provider>
    );
  }
}

或者,您可以在功能組件中使用 React Hooks。 希望這能解決您的問題。

我建議您閱讀React 關於構造函數的文檔以獲取更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM