将函数返回值作为props传递给子组件

时间:2018-04-15 11:25:26

标签: javascript reactjs react-redux

我在父组件的循环中有一个反应子组件渲染。例如在父组件我有这样的:

<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请求。我在imageSRC的{​​{1}}道具上调用该函数。以下是功能。

child component

我希望通过 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传递给子组件但是我没有达到预期效果。我究竟做错了什么?我被卡住了。 感谢

2 个答案:

答案 0 :(得分:0)

您尝试在渲染方法中使用异步方法。

您想要做的是将来自呈现方法的createImageSrc电话转移到componentDidUpdatecomponentDidMount,然后将其设为createImageSrc {1}}在完成提取时更新状态。

这是你应该做的伪代码

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 错误

答案 1 :(得分:0)

问题是子组件不知道什么时候会履行承诺。当承诺履行时,您将告诉子组件。

如果您正在使用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)
  }