如何从外部 JavaScript 文件调用反应函数
Posted
技术标签:
【中文标题】如何从外部 JavaScript 文件调用反应函数【英文标题】:How to call react function from external JavaScript file 【发布时间】:2021-05-07 23:29:59 【问题描述】:我已阅读这篇文章 [ https://brettdewoody.com/accessing-component-methods-and-state-from-outside-react/ ]
但我不明白。
这不适用于我的源代码。
这是我的 tsx 文件
declare global
interface Window
fn_test(): void;
childComponent: htmlDivElement; <-- what the... ref type????
export default function Contact(): React.ReactElement
....
function file_input_html( i:number ): React.ReactElement
return (
<form id=`frm_write_file_$i` .... </form>
)
....
return (
<div ref=(childComponent) => window.childComponent = childComponent>
....
)
这是我的外部 javascript 文件
function fn_test()
window.childComponent.file_input_html(3)
var element = document.getElementById("ifrm_write_file");
// element.value = "mystyle";
如何调用 file_input_html 函数?
请帮帮我...
【问题讨论】:
【参考方案1】:你这里有一些不完全合理的逻辑。
在你的类中,你定义file_input_html
,它返回一个组件。
然后,在fn_test
中,您调用了尝试调用该函数(这不起作用——我将在稍后解决),但您不对输出做任何事情。
您链接到的文章告诉您如何获取组件的引用(例如,在这种情况下为 div
)——而不是实际的 Contact
,它没有名为 file_input_html
的属性-- 这只是你在其作用域内声明的函数。
我假设您想要发生的事情(基于您共享的代码)是让您的外部 javascript 文件能够告诉您的组件呈现具有特定 ID 的表单,然后能够得到它的参考。这是一个如何做到这一点的示例(这有点令人费解,但这是一个有趣的情况):
const useState = React
const App = (props) =>
const [formId, setFormId] = useState(2)
useEffect(() =>
window.alterFormId = setFormId
,[])
return (<div id="form" + formId ref=(ourComponent) => window.ourComponent = ourComponent>
Text formId
</div>);
setTimeout(() =>
window.alterFormId(8);
setTimeout(() =>
console.log(window.ourComponent)
window.ourComponent.innerText = "Test"
, 20)
, 1000)
ReactDOM.render(<App />,
document.getElementById("root"))
这里发生了什么:
-
在
useEffect
中,我在 window
上设置了 alterFormId
,以便可以在 React 文件之外使用它
使用您链接到的技术,我得到一个 ref
到创建的 div。请注意,我也在此处设置 ID,基于 formId
的状态
最后的setTimeout
函数测试了所有这些:
a) 它等到第一次渲染(第一次 setTimeout),然后调用alterFormId
b) 然后,它再次等待(仅 20 毫秒),以便下一个运行循环发生并且 React 组件重新渲染,使用新的 formId 和引用
c) 从那里,它调用 div 上的方法只是为了证明引用有效。
我不太确定您的所有这些用例,并且可能有更简单的方法来构建事物以避免这些问题,但这应该可以帮助您入门。
【讨论】:
【参考方案2】:안녕하세요。 자바스크립트로 흐름만 알려드리겠습니다
아래코드들을참고해보세요。
iframe간통신은
window.postMessage
API와
window.addEventListener('message', handler)
메시지 수신 이벤트 리스너 로 구현할 수있습니다。 보안관련해서도 방어로직이 몇줄 필요합니다(起源체크 등)
在父母中
import React from 'react';
export function Parent ()
const childRef = React.useRef(null);
const handleMessage = (ev) =>
// 방어로직들
if (check ev.origin, check ev.source, ....)
return false;
console.log('handleMessage(parent)', ev)
React.useEffect(() =>
window.addEventListener('message', handleMessage);
// clean memory
return () =>
window.removeEventListener('message', handleMessage);
)
return (
<div>
<iframe ref="childRef" src="child_src" id="iframe"></iframe>
</div>
)
在孩子中
import React from 'react';
export function Iframe ()
const handleMessage = (ev) =>
console.log('handleMessage(child)', ev)
const messagePush = () =>
window.parent.postMessage( foo: 'bar' , 'host:port')
React.useEffect(() =>
window.addEventListener('message', handleMessage);
// clean memory
return () =>
window.removeEventListener('message', handleMessage);
)
return (
<div>
<button onClick=messagePush>Push message</button>
</div>
)
【讨论】:
以上是关于如何从外部 JavaScript 文件调用反应函数的主要内容,如果未能解决你的问题,请参考以下文章
从react typescript组件调用外部Javascript函数