簡體   English   中英

將函數返回值傳遞給子組件作為道具

[英]pass function return value to child component as props

我在父組件的循環中有一個反應子組件渲染。 例如在父組件中,我有這樣的:

<div className="md-grid">
                  {images
                    ? images.map((img, index) => (
                      <PinnedImage
                        key={index}
                        name={img.mediaName}
                        picture={img.downloadURL}
                        imageSRC={this.createImageSrc(img.downlaodURL)}
                        onClick={this.downloadDoc.bind(
                          this,
                          img.downloadURL
                        )}
                      />
                    ))
                    : null}
                </div>

我想在父級中調用一個函數,該函數是使用REST端點向文件服務器授權的fetch請求。 我在child component imageSRC props上調用該函數。 以下是功能。

  async createImageSrc (url) {
    console.log('createImageSrc called', { url })
    if (url) {
      const downlaodURL = `${PROTOCOL}${url}`
      console.log({ downlaodURL })
      const token = localStorage.getItem('access_token')
      const headers = new Headers({ Authorization: `Bearer ${token}` })
      const options = {
        method: 'GET',
        headers,
        mode: 'cors',
        cache: 'default'
      }
      const request = new Request(downlaodURL)
      const finalResponse = await fetch(request, options).then(response => {
        response.arrayBuffer().then(buffer => {
          const base64Flag = 'data:image/jpeg;base64,'
          const imageStr = this.arrayBufferToBase64(buffer)
          const imageSRC = base64Flag + imageStr
          console.log({ imageSRC })
          return imageSRC
        })
      })
      console.log({ finalResponse })
      return finalResponse
    }
  }

arrayBufferToBase64 (buffer) {
    let binary = ''
    const bytes = [].slice.call(new Uint8Array(buffer))
    bytes.forEach(b => {
      binary += String.fromCharCode(b)
    })
    return window.btoa(binary)
  }

我希望將此createImageSrc的結果作為PROPS通過imageSRC={this.createImageSrc(img.downlaodURL)}傳遞給子組件,但我沒有得到預期的結果。 我究竟做錯了什么? 我被困住了。 謝謝

您正在嘗試在渲染方法中使用異步方法。

您要做的是將對createImageSrc的調用從render方法移到componentDidUpdatecomponentDidMount並進行創建,以便您的createImageSrc在完成提取后更新狀態。

這是您應該做什么的偽代碼

async function createImageSrc(url) {
  const imageSRC = fetch();
  return imageSRC;
}

class YourComponent extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      imagesWithSrc: null
    };
  }

  componentDidMount(props) {
    if (props.images) {
      this.fetchImageSrc(props.images);
    }
  }

  fetchImageSrc = (images) => {
    const promises = images.map((img) => createImageSrc(img.downloadURL));
    Promise.all(promises).then((...imageSRCs) => {
      const newImages = images.map((img, idx) => { 
        return {
          ...img,
          imageSRC: imageSRCs[idx]
        };
      });
      this.setState({ imagesWithSrc: newImages });
    });
  }

  render() {
    const { imagesWithSrc } = this.state;
    return (
      <div className="md-grid">
        { imagesWithSrc
           ? imagesWithSrc.map((img, index) => (
              <PinnedImage
                key={index}
                name={img.mediaName}
                picture={img.downloadURL}
                imageSRC={img.imageSRC}
                onClick={this.downloadDoc.bind(
                      this,
                      img.downloadURL
                    )}
              />
            ))
        : null}
      </div>
    );
  }
}

旁注只是想讓您知道您在某些地方拼寫了downloadURL錯誤

問題是子組件將不知道何時會兌現承諾。 當諾言實現時,您將告訴子組件。

如果您使用的是redux,則添加加載的圖像以存儲每個孩子可以在重新渲染時獲得其來源的位置。

    <div className="md-grid">
                  {images
                    ? images.map((img, index) => (
                      <PinnedImage
                        key={index}
                        id={index[or some other unique id]}
                        name={img.mediaName}
                        picture={img.downloadURL}
                        imageSRC={this.createImageSrc(img.downlaodURL,id[same id used as child id])}
                        onClick={this.downloadDoc.bind(
                          this,
                          img.downloadURL
                        )}
                      />
                    ))
                    : null}
                </div>


    async createImageSrc (url,id) {
    console.log('createImageSrc called', { url })
    if (url) {
      const downlaodURL = `${PROTOCOL}${url}`
      console.log({ downlaodURL })
      const token = localStorage.getItem('access_token')
      const headers = new Headers({ Authorization: `Bearer ${token}` })
      const options = {
        method: 'GET',
        headers,
        mode: 'cors',
        cache: 'default'
      }
      const request = new Request(downlaodURL)
      const finalResponse = await fetch(request, options).then(response => {
        response.arrayBuffer().then(buffer => {
          const base64Flag = 'data:image/jpeg;base64,'
          const imageStr = this.arrayBufferToBase64(buffer)
          const imageSRC = base64Flag + imageStr
          console.log({ imageSRC })
            this.props.dispatch ({type:"imageLoaded",payload:{src:imageSRC,id:id}})
       //   return imageSRC
        })
      })
      console.log({ finalResponse })
      return finalResponse
    }
  }

arrayBufferToBase64 (buffer) {
    let binary = ''
    const bytes = [].slice.call(new Uint8Array(buffer))
    bytes.forEach(b => {
      binary += String.fromCharCode(b)
    })
    return window.btoa(binary)
  }

暫無
暫無

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

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