问题
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 -
- Click this link and scroll down to see the reviews related to Chatelaine
- Then in the menu > select Varenna > select Reviews in the horizontal menu and you still see Chatelaine reviews.
- 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.
来源:https://stackoverflow.com/questions/50206298/pull-graphql-data-into-gatsby-browser-js-or-better-solution-please