在 React 和 Meteor 中使用 Coral Talk

Using Coral Talk with React and Meteor

我真的很难在我的应用程序中实现 The Coral Talk Project 评论系统。 我正在尝试将它实现到一个主要是 Meteor 和 React 的项目中。 It's on GitHub

我认为主要问题是这是我第一次需要在 React 中使用脚本标签。
我尝试通过 componentDidMount 中的 dom,通过使用 dangerouslySetHtml, 和几个不同的包来加载脚本,但只有 div 和 src 在检查时显示,但没有页面本身的脚本内容。它的 onload 功能似乎没有触发。

我已经通过设置另一个更简单的 Node/Express 应用程序来确认服务器和嵌入代码功能正常。
这是我试图嵌入我的 React 站点的代码:

<div id="coral_talk_stream"></div>
<script src="http://127.0.0.1:3000/static/embed.js" async onload="
  Coral.Talk.render(document.getElementById('coral_talk_stream'), {
    talk: 'http://127.0.0.1:3000/'
  });
"></script>

如有任何建议,我们将不胜感激。

我会完全在 React 之外做这件事。所以把它放在你的 main.html 中。然后我会,而不是让 onload 只是

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

改为

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

然后,在您的组件中,执行以下操作:

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} />
    );
  }
}

我不是 100% 这会奏效,但它似乎很可能会。

如果您需要让脚本标记仅在有时加载(如在某些页面上),您可以使用类似React Helmet or just Portals 有条件地将脚本标签渲染到你的头上。

使用 Portals 的 100% 未经测试的示例:

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>
    );
  }
}

答案来自另一个论坛,我将其张贴在这里以增加讨论并帮助以后遇到相同问题的其他人:

您不能像那样从 onload 事件中调用 Coral.Talk.render。没有检查要渲染的组件,所以你告诉 coral talk 渲染到一个不存在的元素。您很可能遇到时间问题。

你需要做的是在你的 render 方法中像这样 div 在评论上放置一个 ref 属性

这就是 gotCommentsDiv 可能...

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