如何访问服务器端React中的JSX组件的DOM事件处理程序

我正在使用React构build一个简单的静态视图引擎,目标是呈现静态HTML标记,并生成一个由组件DOM事件(onClick等)填充的js文件。

我做的第一部分的方式是要求一个指定的JSX文件,例如,看起来像这样:

import React from 'React'; export default class Test extends React.Component { clicked() { alert('Clicked the header!'); } render() { return ( <html> <head> <title>{this.props.title}</title> </head> <body> <h1 onClick={this.clicked}>click me!!!</h1> </body> </html> ); } } 

然后,我通过一个NodeJS后端渲染JSX文件,如下所示:

 let view = require('path-to-the-jsx-file'); view = view.default || view; const ViewElement = React.createFactory(view); let output = ReactDOMServer.renderToStaticMarkup(ViewElement(props)); 

它适用于静态HTML。 但是我想知道是否有一种方法可以访问数组中的JSX文件中使用的所有组件,然后我可以使用它来检查绑定了哪些事件以及哪些处理程序。

那么在这个例子中,能够得到<h1> -tag的onClick -handler? 这甚至有可能做些什么?

为了能够从onClick事件中获得一个string的函数,我们需要以下内容:

  1. 元素的DOM
    • 我们可以通过在我们的h1元素上附加一个ref属性来获得这个
  2. 传递给onClick事件的函数的名称(单击)
  3. 函数本身来自包含函数名称的string
    • 由于我们在React组件中方便地使用了方法,我们可以在组件中使用这个['functionName']来获得函数。
  4. 该函数的string化版本

 import React from 'React'; export default class Test extends React.Component { componentDidMount() { // Gets the name of the function passed inside onClick() const nameBound = this.element.props.onClick.name; // Removes 'bound ' from the function name (-> clicked) const nameString = nameBound.replace('bound ', ''); // Gets the function from the function name as a string const convertedFunction = this[nameString]; // Converts the function into string const stringifiedFunction = convertedFunction.toString(); console.log(functionString); } clicked() { alert('Clicked the header!'); } render() { return ( <html> <head> <title>{this.props.title}</title> </head> <body> <h1 ref={(element) => { this.element = element; }} onClick={this.clicked}>click me!!!</h1> </body> </html> ); } } 

经过大量的搞乱之后,我想出了一个很好的解决scheme。

如果我创build自己的ReactElement的实例(在示例ViewElement(props) )中,我可以使用它的标准render函数渲染元素:

 let element = ViewElement(props); let instance = new element.type(); let render = instance.render(); 

从这里我可以通过这个元素的所有道具,所以, onClick handlers将在render.props

所以我所做的是检查每个prop是否匹配一个react-event-name(例如onClick,onDragEnd,onDragEnter等)。 如果是这样,并且这个属性的值是types的函数 – 我有事件名称它的处理函数:

 Object.keys(render.props).map((key) => { if (bigArrayOfAllTheEventNames.indexOf(key) !== -1) { item.events[key] = render.props[key];//check if type is function. } }); 

然后,我也通过render.props.childrenrecursion地遍历所有它的子组件,并将具有事件的每个组件添加到数组中。

剩下的唯一问题是,我需要一种方法将呈现的DOMstring绑定到我现在拥有的JavaScript处理程序。 为此,我添加了一个需要使用自定义的DOM属性,然后可以使用这样的东西来识别组件

$("[data-id=value]").on({event-name}, {it's JS-handler})

这可能不完美,但我认为这是最好的解决scheme。