외부 js파일을 로드하여 사용할 일이 있었다.
단순하게 public/index.html에 추가했는데 실패.
해당 파일이 필요한 컴포넌트 진입 시 로드하는 것으로 수정했다.
useEffect(() => {
if(!document.getElementById("test")) {
const fileScript = document.createElement("script");
fileScript.id = "test";
fileScript.src = "/filepath/test.js";
document.body.appendChild(fileScript);
fileScript.onload = () => {
// do something
};
fileScript.onerror = () => {
console.log("load error!");
};
}
}, []);
훅으로 만들어서 사용할 수도 있다기에 기록해두기.
// useScript.jsx
import { useState, useEffect } from "react";
export default function useScript(url) {
// "idle", "loading", "ready", "error"
const [status, setStatus] = useState(url ? "loading" : "idle");
useEffect(() => {
if (!url){
setStatus("idle");
return;
}
let script = document.querySelector(`script[src="${src}"]`);
if (!script) {
script = document.createElement("script");
script.src = url;
script.async = true;
script.setAttribute("data-status", "loading");
document.body.appendChild(script);
const setAttributeFromEvent = (event) => {
script.setAttribute("data-status", event.type === "load" ? "ready" : "error");
};
script.addEventListener("load", setAttributeFromEvent);
script.addEventListener("error", setAttributeFromEvent);
} else {
setStatus(script.getAttribute("data-status"));
}
const setStateFromEvent = (event) => {
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);
}
}, [url]);
return status;
}
사용할 때는
import { useEffect } from "react";
import useScript from "./hooks/useScript";
export default Test() {
const status = useScript("/filepath/test.js");
useEffect(() => {
if(status === "ready") {
// do something
}
}, []);
}