Remount componentDidMount() by path.name

前端 未结 4 1462
野性不改
野性不改 2021-01-25 23:11

When the page loads I use componentDidMount() to document.createElement(\"script\"); in the layout index.js of a ReactJS and G

相关标签:
4条回答
  • 2021-01-25 23:58

    You can use navigateTo from the gatsby-link package to roll your own Link component that executes your custom logic before navigating.

    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;
    

    I have not tested this code but idea will work.

    0 讨论(0)
  • 2021-01-26 00:00

    Could you use a HOC to accomplish what you want. I just threw this together, it will need to be modified.

    Create a component something like,

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

    Then in react router wrap it like,

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

    And in the component use 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 讨论(0)
  • 2021-01-26 00:05

    componentDidMount runs the first time (and only the first time!) the component is mounted in the DOM.

    componentDidUpdate runs every time the component receives new props, but not for the initial render.

    In order to operate on the DOM for the first render and for subsequent updates, you'll need to register your <script> handling logic in both componentDidMount and componentDidUpdate, i.e.

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

    You can refactor this to move the <script> creation logic into a helper function, but I've inlined it here to make it clear what's going on.

    0 讨论(0)
  • 2021-01-26 00:11

    You can add in the componentDidUpdate lifecycle method which is called whenever the component is updated:

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

    You can add more conditions to match only certain paths.

    Check your gastby-link library to see how you can get the current pathname to pass in as props.

    You can also try passing pathname={window.location.pathname} from a parent component that gets re-rendered when path changes.

    0 讨论(0)
提交回复
热议问题