score:4

Accepted answer

I would do this outside of React entirely. So put that in your main.html. I would then, rather than having the onload just be

Coral.Talk.render(document.getElementById('coral_talk_stream'), {
  talk: 'http://127.0.0.1:3000/'
});

change it to

window.renderCoralTo = function (id) {
  Coral.Talk.render(document.getElementById(id), {
    talk: 'http://127.0.0.1:3000/'
  });
}

Then, in your component, do this:

class CoralTalk extends Component {
  static divId = 'coral_talk_stream';

  shouldComponentUpdate() {
    return !this.rendered; // Stops the div from being remounted
                           // shouldn't be necessary, but a minor precaution
  }

  renderCoral = div => {
    if (!this.rendered && div != null) {
      window.renderCoralTo(CoralTalk.divId);
    }
  };

  render() {
    return (
      <div id={CoralTalk.divId} ref={this.renderCoral} />
    );
  }
}

I'm not 100% this will work, but it seems likely that it would.

If you need to have the script tag only load sometimes (as in on some pages), you can use something like React Helmet or just Portals to conditionally render the script tag to your head.

A 100% untested example using Portals:

class DynamicScript extends Component {
  render() {
    return React.createPortal(
      <script {...this.props} />,
      document.getElementsByTagName('head')[0]
    );
  }
}

class CoralTalk extends Component {
  static divId = 'coral_talk_stream';

  shouldComponentUpdate() {
    return !this.rendered; // Stops the div from being remounted
                           // shouldn't be necessary, but a minor precaution
  }

  render() {
    this.rendered = true;
    return (
      <Fragment>
        <ConditionalScript src="http://127.0.0.1:3000/static/embed.js" async onload={`
          Coral.Talk.render(document.getElementById('${CoralTalk.divId}'), {
            talk: 'http://127.0.0.1:3000/'
          });
        `} />
        <div id={CoralTalk.divId} />
      </Fragment>
    );
  }
}

score:0

Answer taken from another forum, I'm posting it here to add to the discussion and help anyone else having the same issue in the future:

you can not call Coral.Talk.render from the onload event like that. there is no check for the component to be rendered, so you are telling coral talk to render to an element that is not there. you have a timing issue most likely.

what you have to do is in your render method put a ref prop on the comments div like this

this is what gotCommentsDiv could be...

gotCommentsDiv(el) { if (el) Coral.Talk.render(el, {talk: 'http://127.0.0.1:3000/'}); }


Related Query

More Query from same tag