繁体   English   中英

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

[英]How to access DOM event-handlers for JSX-components in server-sided React

我正在使用React构建一个简单的静态视图引擎,其目标是呈现静态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-backend渲染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事件中将函数作为字符串获取,我们需要以下内容:

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

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>
        );
    }
}

在经历了很多混乱后,我提出了一个非常好的解决方案。

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

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

从这里我可以浏览这个元素的所有道具,所以,例如, onClick -handlers将在render.props

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

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

然后我还遍历render.props.children recursivly来访问它的所有子组件,并将每个具有事件的组件添加到数组中。

剩下的唯一问题是我需要一种方法将渲染的DOM字符串绑定到我现在拥有的javascript处理程序。 为此,我添加了一个使用自定义DOM属性的需求,然后可以使用这个属性来识别组件

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

它可能还不完美,但我认为这是最好的解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM