2

我编写了以下组件来在我的 React 应用程序中嵌入一个 Pinterest 小部件:

import React, { Component } from 'react'

class PinterestWidget extends Component {
  componentWillMount() {
    const script = document.createElement('script')

    script.async = true
    script.type = 'text/javascript'
    script['data-pin-build'] = 'doBuild'
    script.src = '//assets.pinterest.com/js/pinit.js'
    document.body.appendChild(script)
  }

  render() {
    const { url } = this.props

    return (
      <a data-pin-do="embedPin" data-pin-build="doBuild" href={url}>
        {url}
      </a>
    )
  }
}

export default PinterestWidget

第一次安装组件时它工作正常。

但是当我导航到另一条路线并返回此页面时,它不再呈现小部件。

我试图将脚本放入componentDidUpdate,但没有成功。

PS:我搜索了一个组件,但我发现的唯一一个是react-pinterest,它没有维护 2 年——并且在我的应用程序中不起作用。

有谁能够帮我?

4

2 回答 2

2

我今天发现自己处于完全相同的位置。在与同一个react-pinterestnpm 包的分叉搏斗之后,我在这个问题https://github.com/pinterest/widgets/issues/13中找到了一个解决方案。

看起来您已经通过添加 data 属性接近了,但是当用户在点击不同的路线后返回到组件时data-pin-build="doBuild"您没有调用。doBuild()添加 data 属性指示pinit.js添加doBuild()到全局范围,但不会在您重新安装组件时自动调用该函数。

尝试用这样的componentWillMount东西替换你的函数:

componentDidMount() {
  if (!window.doBuild) {
    this.preloadWidgetScript();
  } else {
    window.doBuild();
  }
}

preloadWidgetScript = () => {
  const script = document.createElement('script');
  script.async = true;
  script.dataset.pinBuild = 'doBuild';
  script.src = '//assets.pinterest.com/js/pinit.js';
  document.body.appendChild(script);
}

要注意的另一件事是从componentWillMountto的更改componentDidMount,这是确保嵌入链接在运行之前呈现所必需的doBuild()

于 2019-01-18T21:09:05.400 回答
0

在我的情况下,使用@n33kos 的答案,它useEffect每次都可以使用(不检查它是否附加了脚本)。这里<a>指向 pinterest 的链接存在于一个作为 html 注入的降价文件中

  useEffect(() => {
    const script = document.createElement('script')
    script.async = true
    script.type = 'text/javascript'
    script.dataset.pinBuild = 'doBuild'
    script.src = '//assets.pinterest.com/js/pinit.js'
    document.body.appendChild(script)
    if (window.doBuild) window.doBuild()
  }, []) // only run once
于 2019-02-26T17:56:27.860 回答