Wenn die Seite geladen wird, verwende ich componentDidMount () für document.createElement("script"); im Layout index.js eines ReactJS und GatsbyJS -Projekts als

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

Dies fordert dann die Anzeige der Daten an und funktioniert einwandfrei. Wenn ich jedoch <link to=... eine andere Seite mit gatsby-link verwende (stellen Sie sich vor, dass das gleiche Problem für react-router gilt), wurde componentDidMount() bereits ausgeführt, sodass die Daten nicht erneut abgerufen werden.

Wie kann ich sicherstellen, dass dieses Skript nach jeder path Änderung mounted oder besser durch eine bestimmte path ist?

0
Darren 18 Apr. 2018 im 10:18

4 Antworten

Beste Antwort

componentDidMount wird beim ersten (und nur beim ersten Mal!) Ausführen der Komponente im DOM ausgeführt.

componentDidUpdate wird jedes Mal ausgeführt, wenn die Komponente neue Requisiten erhält, jedoch nicht für das anfängliche Rendern.

Um das DOM für das erste Rendern und für nachfolgende Aktualisierungen bearbeiten zu können, müssen Sie Ihre <script> -Verarbeitungslogik sowohl in componentDidMount als auch in componentDidUpdate, dh

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

Sie können dies umgestalten, um die Erstellungslogik <script> in eine Hilfsfunktion zu verschieben, aber ich habe sie hier eingefügt, um zu verdeutlichen, was los ist.

0
bgran 4 Mai 2018 im 19:41

Könnten Sie ein HOC verwenden, um das zu erreichen, was Sie wollen? Ich habe das gerade zusammengeschmissen, es muss modifiziert werden.

Erstellen Sie eine Komponente wie:

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

Dann in React Router Wrap es wie,

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

Und in der Komponente verwenden Sie componentDidMount,

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

        componentDidMount() {
            this.trackIt();
        }

        render() {
            return (
                <div>
                    <h1>something</h1>
                </div>
            );
        }
    }
};
0
Ryan Breece 3 Mai 2018 im 18:14

Sie können navigateTo verwenden aus dem gatsby-link -Paket, um Ihre eigene Link -Komponente zu rollen, die Ihre benutzerdefinierte Logik ausführt, bevor Sie navigieren.

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;

Ich habe diesen Code nicht getestet, aber die Idee wird funktionieren.

1
Liau Jian Jie 29 Apr. 2018 im 20:38

Sie können die Lebenszyklusmethode componentDidUpdate hinzufügen, die bei jeder Aktualisierung der Komponente aufgerufen wird:

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

Sie können weitere Bedingungen hinzufügen, die nur bestimmten Pfaden entsprechen.

Überprüfen Sie Ihre gastby-link Bibliothek, um festzustellen, wie Sie den aktuellen Pfadnamen als Requisiten übergeben können.

Sie können auch versuchen, pathname={window.location.pathname} von einer übergeordneten Komponente zu übergeben, die erneut gerendert wird, wenn sich der Pfad ändert.

0
riwu 28 Apr. 2018 im 17:59