我有以下用例. 来自第三方源的一些HTML被加载到我的React组件中: class MyComponent extends Component { render() { return ( div dangerouslySetInnerHTML={{ __html: this.props.externalHTML }} / ); }} 在外部加载的HTM
来自第三方源的一些HTML被加载到我的React组件中:
class MyComponent extends Component { render() { return ( <div dangerouslySetInnerHTML={{ __html: this.props.externalHTML }} /> ); } }
在外部加载的HTML中,存在特定范围的单击事件,该事件应该调用我的应用程序中存在的回调函数.
<span onclick="myCallback(param1='asd', param2=123, param3='asdas')"> Click me! </span>
我应该把这个myCallback函数放在哪里?
如果我将它放在组件类中,我在单击span时会出现以下错误,因为据我所知,该函数对于外部加载的HTML是不可见的:Uncaught ReferenceError:mySpallback未在HTMLSpanElement.onclick中定义
我的另一个想法是将函数添加到窗口对象window.myCallback = …在我的主index.js文件中,每次加载应用程序时都要加载.这种方式有效,但我有两个问题.
>我的理解是,这不是正确的React方法.
>每当我单击span元素时,回调函数会被触发两次,我无法理解为什么.
有什么建议?
使用“dangerouslySetInnerHTML”是……“危险”的名称^^,它实际上不是纯粹的React方式.但是,如果你必须这样做,你可以做这样的事情(利用React内置的jQuery是默认的)
=====
从这里编辑版本:(仅使用1个组件)
export default class MyComponent extends Component { componentDidMount() { // using jQuery to manipulate DOM element form third-party source // NB. you may think of using setTimeout here, to wait for the external source to be fully loaded here, of course it's not so safe // but anyway, we are using "dangerouslySetInnerHTML" anyway => quite dangerous, though ^^ // setTimeout(function(){ $(document.findElementsByTagName("span")[0]).click(function(e){ // or perhaps $("#spanID").click if you can, just be careful between DOM element and react component e.preventDefault(); // DO SOMETHING HERE, just like you do in the window.onload function // or maybe you also need to get param values by getting $(this).data("...") or $(this).attr("ATTRIBUTE-NAME") return false; }); // }); } render() { return ( <div dangerouslySetInnerHTML={{ __html: this.props.externalHTML }} /> ); } }
=====
从这里回答:(使用2个组件)
为父级:
export default class MyComponent extends Component { constructor(props) { super(props); this.callbackOnThisComponent = this.callbackOnThisComponent.bind(this); } callbackOnThisComponent(param1, param2, param3) { // do whatever you like with the above params } render() { return ( <ChildComponent triggerCallbackOnParent={this.callbackOnThisComponent} /> ); } }
ChildComponent:
export default class ChildComponent extends Component { componentDidMount() { // using jQuery to manipulate DOM element form third-party source let that = this; // NB. you may think of using setTimeout here, to wait for the external source to be fully loaded here, of course it's not so safe // but anyway, we are using "dangerouslySetInnerHTML" anyway => quite dangerous, though ^^ $(document.findElementsByTagName("span")[0]).click(function(e){ // or perhaps $("#spanID").click if you can, just be careful between DOM element and react component e.preventDefault(); that.props.triggerCallbackOnParent(param1, param2, param3); // or maybe you need to get param values by getting $(this).data("...") or $(this).attr("ATTRIBUTE-NAME") return false; }, that); } render() { return ( <div dangerouslySetInnerHTML={{ __html: this.props.externalHTML }} /> ); } }
我只是使用React的主要思想,它将props向下传递给子组件,当你想从子组件向上触发一个函数时,在parent上创建一个回调函数.对于您或其他任何人的参考,这是我演示如何将回调函数从父级传递到多级子组件:
Force React container to refresh data
Re-initializing class on redirect
如果这还不行,请随时向我显示一些错误日志,谢谢