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?
4 Antworten
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.
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>
);
}
}
};
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.
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.