按 path.name 重新挂载 componentDidMount()
Remount componentDidMount() by path.name
当页面加载时,我在 ReactJS 和 GatsbyJS[= 的布局 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>
创建逻辑移动到辅助函数中,但我在此处将其内联以明确发生了什么。
当页面加载时,我在 ReactJS 和 GatsbyJS[= 的布局 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>
创建逻辑移动到辅助函数中,但我在此处将其内联以明确发生了什么。