[英]Call function on 'window' DOM object created in dynamic script for a React component
在 ReactJS 組件中,我需要調用通過動態創建的腳本定義的函數(通過窗口對象)。 為了更好地理解,我有以下示例。 這是一個簡化的代碼示例:
文件 RFo.js:
//Generic helper function for create a script of only code (not src):
function SetScript(id, code) {
if (!document.getElementById(id)) //Only if script not already exists
{
const script = document.createElement("script");
script.type = 'text/babel';
script.textContent = code;
script.id = id;
script.async = true;
document.body.appendChild(script);
}
}
//Calling this function outside of RFo component, it works!
SetScript("myScriptId", "function myFunc(v) { return v+1; }");
// RFo component
export const RFo = () =>
{
//console debug
console.log(document.getElementById("myScriptId")); //always shows the script created
console.log(window["myFunc"]); //it works as SetScript function was called outside RFo component
return (
<div>
MyFunc result: {window["myFunc"](10)}
</div>
);
}
我的問題是調用SetScript("myScriptId", "function myFunc(v) { return v+1; }");
我想把它放在 RFo 組件中(因為腳本代碼可以作為道具發送)。 例子:
// RFo component
export const RFo = () =>
{
//moved inside RFo component
SetScript("myScriptId", "function myFunc(v) { return v+1; }");
//console debug
console.log(document.getElementById("myScriptId")); //always shows the script created
console.log(window["myFunc"]); //shows 'undefined' as SetScript function is called inside RFo component
return (
<div>
MyFunc result: {window["myFunc"](10)}
</div>
);
}
如果我把它放在 RFo 組件內,它就不起作用。 我想這應該是一些簡單和概念性的東西,或者可能是一種解決方法。 我是 React 和 JS 的新手。 我真的很感謝你的幫助。
我不明白您為什么要將新的腳本組件添加到 DOM 中,這應該是一種不好的做法,您可以這樣做:
function SetScript(functionName, callback){
window[functionName] = callback
}
然后在 react 組件中定義全局函數:
export const RFo = () =>
{
// Pass function to second parameter instead of string
SetScript("myFunc", function myFunc(v) {
return v+1;
});
// Print global function to console
console.log(window["myFunc"])
return (
<div>
MyFunc result: {window["myFunc"](10)}
</div>
);
}
你可以在codepen中看到它
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.