Update TradingView Hotlist Widget onChange

Below is my component for firing up the widget, I would like to change the exchange when a new value is selected from the select tag. The onChange changes the state value, however the widget doesn’t change the values it’s looking at. Any ideas how to make it work?

import React from "react"; 

export default  class StockGainer extends React.PureComponent {
    constructor(props) {
        super(props);
        this._ref = React.createRef();
        this.state = { 
        exchange:
         "TSX" 
        }
    }
 componentDidMount() {
        const script = document.createElement('script');
        script.src = 'https://s3.tradingview.com/external-embedding/embed-widget-hotlists.js' 
        script.async = true;
        this._ref.current.appendChild(script);
        script.innerHTML = JSON.stringify(
            {
                  "colorTheme": "dark",
                  "dateRange": "12M",
                  "exchange": `${this.state.exchange}`,
                  "showChart": true,
                  "locale": "en"
                })
    }
   


    render() {

        const Changeexchange = (e) => { 

            this.setState({exchange: e.target.value})
        }  

        const SelectBox = () => (
            <div class="select-div">
            <select className="exchange" value={this.state.exchange} name="pagination" onChange={Changeexchange}>
              <option value="US"> USA (US Exchanges)</option>
              <option value="NASDAQ"> USA (NASDAQ)</option>
              <option value="NYSE"> USA (NYSE)</option>
              <option value="AMEX"> USA (NYSE ARCA)</option>
              <option value="OTC"> USA (OTC)  </option>
            </select>
            </div>
        )

        return(
          
        <div class="tradingview-widget-container" ref={this._ref}>
            <div style={{position:"absolute", top: "0px", left:"318px"}}>{SelectBox()}</div> 
         <div class="tradingview-widget-container__widget"> </div>
          {console.log(this.state.exchange)}
        </div>
        );
    }
   
}

Answer

You can add id to your element (iframe in this case) and then on select onChange call you can delete the previous iframe based on the stored element id and then create a fresh element.

Working Example With Comments

Code –

Changeexchange = (e) => {
    this.setState({ exchange: e.target.value });

    // Remove the existing DOM elem
    const elem = document.getElementById(this.currentDOMId);
    elem.parentNode.removeChild(elem);

    // Create a new elem with updated values
    // so that updated iframe will load
    const script = document.createElement("script");
    script.id = `dom-exchng-id-${this.state.exchange}`;
    this.currentDOMId = `dom-exchng-id-${this.state.exchange}`;
    script.src =
      "https://s3.tradingview.com/external-embedding/embed-widget-hotlists.js";
    script.async = true;
    this._ref.current.appendChild(script);
    script.innerHTML = JSON.stringify({
      colorTheme: "dark",
      dateRange: "12M",
      exchange: e.target.value,
      showChart: true,
      locale: "en"
    });
  };

Fyi, I have formatted your code a bit, as you are referring className as class in your code.