【问题标题】:How to call react function from external JavaScript file如何从外部 JavaScript 文件调用反应函数
【发布时间】: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 函数?

请帮帮我...

【问题讨论】:

    标签: reactjs typescript react-native typescript-typings


    【解决方案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"))
    

    这里发生了什么:

    1. useEffect 中,我在 window 上设置了 alterFormId,以便可以在 React 文件之外使用它
    2. 使用您链接到的技术,我得到一个 ref 到创建的 div。请注意,我也在此处设置 ID,基于 formId 的状态
    3. 最后的setTimeout 函数测试了所有这些: a) 它等到第一次渲染(第一次 setTimeout),然后调用alterFormId b) 然后,它再次等待(仅 20 毫秒),以便下一个运行循环发生并且 React 组件重新渲染,使用新的 formId 和引用 c) 从那里,它调用 div 上的方法只是为了证明引用有效。

    我不太确定您的所有这些用例,并且可能有更简单的方法来构建事物以避免这些问题,但这应该可以帮助您入门。

    【讨论】:

      【解决方案2】:

      안녕하세요。 자바스크립트로 흐름만 알려드리겠습니다

      아래코드들을참고해보세요。

      iframe간통신은

      window.postMessageAPI와 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>
        )
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-05-06
        • 1970-01-01
        • 2013-09-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-25
        相关资源
        最近更新 更多