Pull GraphQL data into gatsby-browser.js (or bette

2019-05-15 04:38发布

问题:

I am trying to run a GraphQL query inside replaceRouterComponent from within gatsby-browser.js (gatsby browser API). Whereas, I can access data from Contentful.

This may not be the best solution and any advice on how I can achieve in another way would be appreciated too.

Here is the issue -

Inside of the component TripAdvisor.js I am mounting the scripts within componentDidMount, whereas the locationId is based on the data of this.props.tripAdvisorId pulled from the individual posts created in Contentful. Each post (property) has an individual locationId that when changed in the script src presents the reviews that relate.

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

    const tripadvisorRight = document.createElement("script");
    tripadvisorRight.src = "https://www.jscache.com/wejs?wtype=selfserveprop&uniq=998&locationId=" + this.props.tripAdvisorId + "&lang=en_AU&rating=false&nreviews=4&writereviewlink=false&popIdx=false&iswide=true&border=false&display_version=2";
    tripadvisorRight.async = true;
    document.body.appendChild(tripadvisorRight);
}

I also have a function inside componentDidMount at page level to rewrite the data from the TripAdvisor script above. The TripAdvisor script creates a function called injectselfserveprop*** (where *** are random numbers). Without this, the function is not called when reaching the Component with Link

/templates/properties/reviews.js

componentDidMount() {
  Object.keys(window).forEach((key) => {
      if (key.match(/^injectselfserveprop[0-9]+$/)) {
          window[key]();
      }
  });
}

In the same file of /templates/properties/reviews.js I use shouldComponentUpdate to return false as it stops the TripAdvisor from continually updating between pages (causing it to break) when using link

shouldComponentUpdate() {
  return false;
}

Now, where this solution falls apart is in changing the locationId of the script src. It works perfectly fine if I did not need to change the locationId per post.

It fails when link to another post with a different locationId and the reviews component not updating. However, then link away and return to the new reviews.

You can see this happening here and following these steps -

  1. Click this link and scroll down to see the reviews related to Chatelaine
  2. Then in the menu > select Varenna > select Reviews in the horizontal menu and you still see Chatelaine reviews.
  3. Now, click on > Location in the horizontal menu > then click Reviews again > you get the correct reviews and count for Varenna.

There is a GitHub repository for the full site here. The two files to look for are in /src/templates/properties/reviews.js and src/components/properties/TripAdvisor.js

Now I have outlined my issue, I believe the best solution is within gatsby-browser.js wrapping the TripAdvisor scripts inside replaceRouterComponent with a conditional statement to apply only to pages that directly access the reviews.js via Link.

However, I cannot find a solution in using the tripAdvisorID data inside gatsby-browser.js (gatsby browser API). Whereas, I can access data from Contentful using GraphQL.

If you have another solution then please let me know.

回答1:

Well, If your problem is the updating the component maybe the problem is in the way you are dealing with side effects (the componentDidMount fetch in TripAdvisor).

For what I can see, the data that you receive in props is all good, and it should fetch, but there is an error. componentDidMount will ONLY BE CALLED ONCE, and this time is the first time the component has been loaded in the page. So it doesnt matter that your props change and that you render again, the code in componentDidMount won't be called again.

You could do the fix in 2 ways. Rather you add key in

 <TripAdvisor key={tripAdvisorId} name={name} starRating={starRating} location={location} tripAdvisorId={tripAdvisorId} * />

This way react will unmount the previous TripAdvisor and mount a new one thereby calling the componentDidMount method again... What could be a bit of a problem if you have to be remounting everything just for a different data from the props....

I could recommend you a second way, that is also the way they recommend in the React Documentation. Instead of realizing your changes in componentDidMount, do them in componentDidUpdate(prevProps, prevState) (NOTE: You will need to safe your fetch by this.props.tripAdvisorId !== prevProps.tripAdvisorId or you will enter a infinite loop).

I think that this is the problem for you to update the data, nothing gatsby related... But comment me if the problem persist and I could check further into the GraphQL problems that you are running into.