javascriptreactjssvgcallbackasynchronous-javascript

Call a method in child component only after parent completes re-render


I have a graph with lower graphic quality displayed by a parent component<HeatMap />. HeatMap has a child component, <MyButton {...data}>. MyButton is basically a button, which is dowloads the graph image. My requirement is: after button is clicked, the parent(HeatMap) should get re-rendered into a high quality svg image. And only after that, the download should happen.

What I have been able to achieve: On clicking the button for the first time, quality of the image changes into an svg, but png image gets downloaded. I think the downloading starts before the the parent is completely rendered.

Code:

class HeatMap extends Component {
  constructor (props) {
    super(props);
    this.state = {
      getSVG: false,
      loadedData: [],
    }
  }
  render () {
   const { getSVG, loadedData } = this.state;
   return (
    <Fragment>
      {getSVG
        ? <HeatmapSeries colorType="literal" data={loadedData} /> // svg graph
        : <HeatmapSeriesCanvas colorType="literal" data={loadedData} />} // png(low-qlty)
      <MyButton 
        {...this.props}
        svgFunction={(required) => this.setState({ getSVG: true})}
        getSVG={getSVG} 
       />
    </Fragment>
  )
  }
}
class MyButton extends Component {
  render() {
    return (
      <Button size="small" icon="download" onClick={this._downloadSVG} >SVG</Button>
    )
  }
  /**
   * Generate the image and the download action
   * @return {void}
  **/
  async _downloadSVG() {
    const { svgFunction } = this.props;
    if (typeof svgFunction === 'function') {
      svgFunction(); // re-render the graph as a vector (try to re-render parent first)
    }
    methodToDownloadGraph({...this.props}); // graph svg is passed as argument
  }
}

Problem is : methodToDownloadGraph completes before, re-render of parent completes. Here is a picture of what I want to achieve: enter image description here


Solution

  • Try This One

    async _downloadSVG() {
            const { svgFunction } = this.props;
            if (typeof svgFunction === 'function') {
              await svgFunction(); // Add this line as it is
            }
            methodToDownloadGraph({...this.props}); // graph svg is passed as argument
          }