按 path.name 重新挂载 componentDidMount()

Remount componentDidMount() by path.name

当页面加载时,我在 ReactJSGatsbyJS[= 的布局 index.js 中使用 componentDidMount() 来 document.createElement("script"); 29=] 项目为

componentDidMount () {
  const tripadvisorLeft = document.createElement("script");
  tripadvisorLeft.src = "https://www.jscache.com/wejs?wtype=selfserveprop&uniq=789&locationId=10467767&lang=en_NZ&rating=true&nreviews=0&writereviewlink=true&popIdx=true&iswide=true&border=false&display_version=2";
  tripadvisorLeft.async = true;
  document.body.appendChild(tripadvisorLeft);
}

然后请求显示数据并且工作正常。但是,当我 <link to=... 另一个页面使用 gatsby-link 时(假设同样的问题适用于 react-router),componentDidMount() 已经 运行 所以它不会获取再次获取数据。

如何确保此脚本在每次 path 更改后都是 mounted,或者通过特定的 path 更好?

您可以添加组件更新时调用的 componentDidUpdate 生命周期方法:

componentDidUpdate(prevProps) {
  // check if path has changed
  if (prevProps.pathname !== this.props.pathname) { 
    // call something to fetch data
  }
}

您可以添加更多条件以仅匹配某些路径。

检查您的 gastby-link 库,了解如何获取当前路径名以作为 props 传入。

您也可以尝试从父组件传递 pathname={window.location.pathname},该组件在路径更改时会重新呈现。

您可以使用 gatsby-link 包中的 navigateTo 来滚动您自己的 Link 组件,在导航之前执行您的自定义逻辑。

Link.jsx

import React from "react";
import { navigateTo } from "gatsby-link";

const RESOURCE_PATH = "https://www.jscache.com/wejs?wtype=selfserveprop&uniq=789&locationId=10467767&lang=en_NZ&rating=true&nreviews=0&writereviewlink=true&popIdx=true&iswide=true&border=false&display_version=2";
const refetchAndNavigate = (path) => () => {
  // refetch
  const tripadvisorLeft = document.createElement("script");
  tripadvisorLeft.src = RESOURCE_PATH;
  tripadvisorLeft.async = true;
  document.body.appendChild(tripadvisorLeft);

  // finally navigate
  navigateTo(path);
}

const Link = ({ to, ...propsToPass }) => (
  <div {...propsToPass} onClick={refetchAndNavigate(to)}/>
);

export default Link;

我还没有测试过这段代码,但我的想法是可行的。

你能不能使用 HOC 来完成你想要的。我只是把它放在一起,它需要修改。

创建一个类似的组件,

const withTracking = (WrappedComponent) => {
    return class withTracking extends React.Component {
        constructor(props) {
            super(props);

            this.trackit = this.trackIt.bind(this);
        }

        trackIt() {
            {
                const tripadvisorLeft = document.createElement("script");
                tripadvisorLeft.src = "https://www.jscache.com/wejs?wtype=selfserveprop&uniq=789&locationId=10467767&lang=en_NZ&rating=true&nreviews=0&writereviewlink=true&popIdx=true&iswide=true&border=false&display_version=2";
                tripadvisorLeft.async = true;
                document.body.appendChild(tripadvisorLeft);
            }
        }

        render() {
            return (
                <div>
                    <WrappedComponent {...this.props} trackIt={this.trackIt} />
                </div>
            );
        }
    }
};

然后在 React router 中将其包裹起来,

<Route exact path="/pet-of-the-week" component={withTracking(TEST)}/>

并且在组件中使用componentDidMount,

const TEST = (WrappedComponent) => {
    return class ClickLogger extends React.Component {
        constructor(props) {
            super(props);
        }

        componentDidMount() {
            this.trackIt();
        }

        render() {
            return (
                <div>
                    <h1>something</h1>
                </div>
            );
        }
    }
};

componentDidMount 第一次运行(也是第一次!)组件安装在 DOM 中。

componentDidUpdate 每次组件收到新道具时都会运行,但不会在初始渲染时运行。

为了在 DOM 上进行首次渲染 和后续更新 的操作,您需要在 <script> 中注册您的处理逻辑componentDidMount componentDidUpdate,即

class YourComponent extends React.Component {
  componentDidMount () {
    const tripadvisorLeft = document.createElement("script");
    tripadvisorLeft.src = "https://www.jscache.com/wejs?wtype=selfserveprop&uniq=789&locationId=10467767&lang=en_NZ&rating=true&nreviews=0&writereviewlink=true&popIdx=true&iswide=true&border=false&display_version=2";
    tripadvisorLeft.async = true;
    document.body.appendChild(tripadvisorLeft);

    // Keep track of the script tag
    this.scriptTag = tripadvisorLeft
  }

  componentDidUpdate (prevProps) {
    // Figure out if the path changed
    if (this.props.path !== prevProps.path) {
      // Remove the old script tag
      document.body.removeChild(this.scriptTag)

      // Add it back
      const tripadvisorLeft = document.createElement("script");
      tripadvisorLeft.src = "https://www.jscache.com/wejs?wtype=selfserveprop&uniq=789&locationId=10467767&lang=en_NZ&rating=true&nreviews=0&writereviewlink=true&popIdx=true&iswide=true&border=false&display_version=2";
      tripadvisorLeft.async = true;
      document.body.appendChild(tripadvisorLeft);

      this.scriptTag = tripadvisorLeft
    } 
  }
}

您可以重构它以将 <script> 创建逻辑移动到辅助函数中,但我在此处将其内联以明确发生了什么。