问题
I'm building an online gallery in React, and it requires an external script in order to work properly.
There are 2 main components, namely Home.js and Single.js. Home.js displays some categories the images are organized in, and the Single.js is the detail view of a category (it contains all the photos under a specific category). The Router looks like this:
<Provider store={ store }>
<Router
forceRefresh={ false }>
<div id="router">
<Switch>
<Route exact path='/' render={ () => <MainLayout><Home /></MainLayout> } />
<Route exact path='/about' render={ () => <MainLayout><About /></MainLayout> } />
<Route path='/single/:id' render={ (props) => <MainLayout><Single {...props} /></MainLayout> } />
</Switch>
</div>
</Router>
</Provider>
I am loading the script 'main.js' using this function:
appendScripts() {
const main = document.createElement('script');
main.src = '/js/main.js';
main.async = true;
main.id = 'main';
document.body.appendChild(main);
}
Now the thing is that the script loads on the Home.js component, but it won't load on the Single.js component only the second time I access it through the home page (for the same category), even though it is appended in the DOM. And the same thing goes for accessing the home page through Single.js. If Single.js loads first, I need to access the Home.js 2 times through the Single.js for the script to load properly.
The components both have these functions called:
componentDidMount() {
this.appendScripts();
}
componentWillMount() {
this.props.getImages(this.state.id);
this.props.getCategory(this.state.id);
}
Any thoughts?
回答1:
I have a similar use case as yours, it is on demand loading of Google's Recaptcha. The key idea to ensure script is loaded before rendering components which access the external script. Here is a simple example
- create a state named loading
- componentDidMount, append the script tag, set onload callback, and set src.
- when script loaded it calls onload to setState({ loading: false })
- do conditional rendering { !loading &&
<MyCompUseExternalScript/>
}
i've copied the code here https://gist.github.com/kykean/29edc055e75a39bdcd329d3323f8bf0b The example uses recompose and is a HOC but the core idea is similar.
回答2:
My guess is that since ReactRouter doesn't actually refresh the page, the script is being cached and just presented a second time without being run. I would put the script into a function and then call it somewhere else, possibly in componentDidMount
, or at least register a listener for when the script is loaded and run it.
来源:https://stackoverflow.com/questions/49325978/react-js-external-script-loading