【问题标题】:React - calling async function from render()React - 从 render() 调用异步函数
【发布时间】:2019-07-16 17:35:31
【问题描述】:

我正在尝试编写我的第一个 React 应用程序,它应该为不同的输入生成 QR 码并将它们显示在网页上。

我已经有自己的“库”函数来为我做这件事——我只将数据作为参数传递,它返回一个数据 URL 的承诺,我将其用作图像的 src,然后就完成了。下面是它现在的工作方式:

class App extends Component {

    constructor(props){
        super(props);
        this.state = {
            dataUrl: '',
        }
    }

    async componentDidMount(){
        let url = await getDataURL('<some imaginary static data>');
        this.setState({dataUrl: url});
    }

    render() {
        return(
            <div className="App">
                <div>
                    <img alt="" src={this.state.dataUrl} style={{height: 200 + 'px', width: 200 + 'px'}} />
                </div>
            </div>
        );
    }
}

但是现在我需要多次调用getDataURL() 来获取一些真实数据,例如我可能有多个具有不同数据的&lt;div&gt;,我需要获取并呈现每个&lt;div&gt; 的二维码。

如果我有一个函数,是这样的:

async loadQRCode(data){
    let url = await getDataURL(data);
    return url;
}

有什么方法可以直接从render() 函数中为每个数据调用它吗?或者有没有更好的方法我错过了?

【问题讨论】:

  • 不要从render()调用函数。你要做的是 a) 更新你的 state (使用尽可能多的异步操作) 和 b) 渲染() 状态。 a) 和 b) 独立发生,并且由于 React 会在状态改变时重新渲染,所有 render() 需要做的就是渲染 current 状态;它不必担心其他任何事情。因此,如果您有多个 QR 码,请在您所在的州为它们使用一个数组。
  • @ChrisG 他有一个函数loadQRCode,它返回一个图像url,这很好用在渲染中。
  • @TheReason 即使函数是异步的?我在看this。我想它会起作用的,我只是想知道这是否是一个好习惯。

标签: javascript reactjs async-await


【解决方案1】:

首先我想说componentDidMount函数是static函数。

但是您可以拥有像 loadQRCode 这样的异步函数,您可以在其中调用该函数并迭代 API 调用并将结果推送到 array 中,然后您可以使用所需的渲染 div数据。

【讨论】:

    【解决方案2】:

    你尝试过这样的事情吗?

    // some code before
    this.state.listOfImages.map((image, i) =>
      <div>
        <img
          alt=""
          src={this.loadQRCode(image.src)}
          style={{height: 200 + 'px', width: 200 + 'px'}}
        />
      </div>
    
    )
    // some code after
    

    您可能需要在`constructor 中绑定getDataURL 方法

    【讨论】:

    • 但这不是重新计算每次渲染时所有的二维码dataURLs吗?
    【解决方案3】:

    我在构造函数中使用对象数组解决了这个问题:

    constructor(props){
        super(props);
        this.state = {
            qrCodeData: [
                {
                    data: <data>
                    qrcode: ''
                },
                {
                    data: <data>
                    qrcode: ''
                },
                ...
            ]
        }
    }
    

    componentDidMount() 中,我遍历数组并调用我的getDataURL() 函数来设置qrcode

    async componentDidMount(){
        let qrCodeDataCopy = this.state.qrCodeData.slice();
        for (let item of qrCodeDataCopy) {
            item.qrcode = await getDataURL(item.data);
        }
        this.setState({qrCodeData: qrCodeDataCopy});
    }
    

    【讨论】:

      【解决方案4】:

      componentDidMount 中调用API 请求很好。之后就可以拨打setState了。

      async componentDidMount(){
              const result = await loadQRCode(`your params`);
              this.setState({ result });
          }
      

      【讨论】:

      • OP 知道这样做。就所提出的问题而言,我看不出这个答案提供了什么?
      猜你喜欢
      • 2016-10-23
      • 2020-04-20
      • 1970-01-01
      • 2019-08-28
      • 2017-08-13
      • 1970-01-01
      • 2017-07-20
      • 1970-01-01
      • 2022-01-25
      相关资源
      最近更新 更多