'How to import js file from url and initialize a class in React?
I want to embed PitchPrint app on a React website. They have a vanilla html/js integration tutorial here. I added script tags with links to jQuery and their app file in my index.html file, as they require and then created a separate jsx file that suposed to return a button witch opens the app. The problem is, when I try to build, it throws an error 'PitchPrintClient' is not defined witch suposed to come from their files. My index.html file:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://pitchprint.io/rsc/js/client.js"></script>
<title>App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
My jsx file:
import React from 'react';
const AppButton = () => {
let _launchButton = document.getElementById('launch_btn');
let _previewDiv = document.getElementById('pp_preview_div');
let _loaderDiv = document.getElementById('pp_loader_div');
_launchButton.setAttribute('disabled', 'disabled');
var ppclient = new PitchPrintClient({
apiKey: 'f80b84b4eb5cc81a140cb90f52e824f6', //Kinldy provide your own APIKey
designId: '3d8f3899904ef2392795c681091600d0', //Change this to your designId
custom: true
});
//Function to run once the app is validated (ready to be used)
var appValidated = () => {
_launchButton.removeAttribute('disabled'); //Enable the Launch button
_launchButton.onclick = () => ppclient.showApp(); //Attach event listener to the button when clicked to show the app
_loaderDiv.style.display = 'none'; //Hide the loader
};
//Function to run once the user has saved their project
var projectSaved = (_val) => {
let _data = _val.data; //You can console.log the _data varaible to see all that's passed down
if (_data && _data.previews && _data.previews.length) {
_previewDiv.innerHTML = _data.previews.reduce((_str, _prev) => `${_str}<img src="${_prev}">`, ''); //Show the preview images
}
};
ppclient.on('app-validated', appValidated);
ppclient.on('project-saved', projectSaved);
return <div>
<div id="pp_loader_div"><img src="https://pitchprint.io/rsc/images/loaders/spinner_new.svg" /></div>
<button id="launch_btn" >Launch Designer</button>
<div id="pp_preview_div"></div>
</div>;
};
export default AppButton;
PS: I know getElementById does not realy work with react, I'll deal with that later, for now I just want to initialize this app.
Solution 1:[1]
that's because the component is not mounted yet.
you need to call document.getElementById once the component is mounted, and in order to access dom elements inside the component you need to call it inside useEffect hook
useEffect(() => {
let _launchButton = document.getElementById("launch_btn");
let _previewDiv = document.getElementById("pp_preview_div");
let _loaderDiv = document.getElementById("pp_loader_div");
_launchButton.setAttribute("disabled", "disabled");
var ppclient = new PitchPrintClient({
apiKey: "f80b84b4eb5cc81a140cb90f52e824f6", //Kinldy provide your own APIKey
designId: "3d8f3899904ef2392795c681091600d0", //Change this to your designId
custom: true,
});
//Function to run once the app is validated (ready to be used)
var appValidated = () => {
_launchButton.removeAttribute("disabled"); //Enable the Launch button
_launchButton.onclick = () => ppclient.showApp(); //Attach event listener to the button when clicked to show the app
_loaderDiv.style.display = "none"; //Hide the loader
};
//Function to run once the user has saved their project
var projectSaved = (_val) => {
let _data = _val.data; //You can console.log the _data varaible to see all that's passed down
if (_data && _data.previews && _data.previews.length) {
_previewDiv.innerHTML = _data.previews.reduce(
(_str, _prev) => `${_str}<img src="${_prev}">`,
""
); //Show the preview images
}
};
ppclient.on("app-validated", appValidated);
ppclient.on("project-saved", projectSaved);
}, []);
Read more about React hooks and their constraints. https://reactjs.org/docs/hooks-intro.html
also make sure to access global variables using window.PitchPrintClient
also, make sure your app is mounted once the dom is ready. by moving your script tags to the end of the body tag or using jquery on ready callback.
PS: The answer is not considering the best practices of writing react components, but I encourage you to use refs and minimize accessing to dom as much as you could.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
