PromucFlow_constructor/app/client/src/utils/hooks/useScript.tsx
satbir121 8bf80fe507
Google Recaptcha integration for button and form button widgets. (#1118)
* Adding base code for google re-captcha.

* Removing recaptcha as well

* Adding recaptchaToken on Button.

* Fixing updateMetaProperty errors.

* Handling recaptcha generation failed case.

* Adding a message for recaptcha token gen fail

* Rename setRecaptchaToken

* Adding loading state for recaptcha button

* Adding googleRecaptchaKey as a Btn prop

* Adding the bound functions in widgets

* Removing unused vars.

* Handling google recaptcha key error.

* Adding proper messages for
2020-10-12 18:31:19 +05:30

70 lines
2.3 KiB
TypeScript

import { useState, useEffect } from "react";
// Hook
export default function useScript(src: string) {
// Keep track of script status ("idle", "loading", "ready", "error")
const [status, setStatus] = useState(src ? "loading" : "idle");
useEffect(
() => {
// Allow falsy src value if waiting on other data needed for
// constructing the script URL passed to this hook.
if (!src) {
setStatus("idle");
return;
}
// Fetch existing script element by src
// It may have been added by another intance of this hook
let script = document.querySelector(`script[src="${src}"]`) as any;
if (!script) {
// Create script
script = document.createElement("script");
script.src = src;
script.async = true;
script.setAttribute("data-status", "loading");
// Add script to document body
document.body.appendChild(script);
// Store status in attribute on script
// This can be read by other instances of this hook
const setAttributeFromEvent = (event: any) => {
script.setAttribute(
"data-status",
event.type === "load" ? "ready" : "error",
);
};
script.addEventListener("load", setAttributeFromEvent);
script.addEventListener("error", setAttributeFromEvent);
} else {
// Grab existing script status from attribute and set to state.
setStatus(script.getAttribute("data-status"));
}
// Script event handler to update status in state
// Note: Even if the script already exists we still need to add
// event handlers to update the state for *this* hook instance.
const setStateFromEvent = (event: any) => {
setStatus(event.type === "load" ? "ready" : "error");
};
// Add event listeners
script.addEventListener("load", setStateFromEvent);
script.addEventListener("error", setStateFromEvent);
// Remove event listeners on cleanup
return () => {
if (script) {
script.removeEventListener("load", setStateFromEvent);
script.removeEventListener("error", setStateFromEvent);
}
};
},
[src], // Only re-run effect if script src changes
);
return status;
}