onClick 处理程序未向 ReactDOMServer.renderToString 注册

Posted

技术标签:

【中文标题】onClick 处理程序未向 ReactDOMServer.renderToString 注册【英文标题】:onClick handler not registering with ReactDOMServer.renderToString 【发布时间】:2016-07-19 07:30:21 【问题描述】:

我正在尝试复制这个小提琴: http://jsfiddle.net/jhudson8/135oo6f8/

(我也试过这个例子 http://codepen.io/adamaoc/pen/wBGGQv 并且存在相同的onClick 处理程序问题)

并使用ReactDOMServer.renderToString 使小提琴为服务器端渲染工作

我有这个电话:

   res.send(ReactDOMServer.renderToString((
            <html>
            <head>

                <link href='/styles/style-accordion.css' rel='stylesheet' type='text/css'></link>

            </head>

            <body>


            <Accordion selected='2'>
                <AccordionSection title='Section 1' id='1'>
                    Section 1 content
                </AccordionSection>
                <AccordionSection title='Section 2' id='2'>
                    Section 2 content
                </AccordionSection>
                <AccordionSection title='Section 3' id='3'>
                    Section 3 content
                </AccordionSection>
            </Accordion>
            </body>
            </html>
        )));

Accordion 元素如下所示:

const React = require('react');

const fs = require('fs');
const path = require('path');


const Accordion = React.createClass(

    getInitialState: function () 
        // we should also listen for property changes and reset the state
        // but we aren't for this demo
        return 
            // initialize state with the selected section if provided
            selected: this.props.selected
        ;
    ,

    render: function () 

        // enhance the section contents so we can track clicks and show sections
        const children = React.Children.map(this.props.children, this.enhanceSection);

        return (
            <div className='accordion'>
                children
            </div>
        );
    ,

    // return a cloned Section object with click tracking and 'active' awareness
    enhanceSection: function (child) 

        const selectedId = this.state.selected;
        const id = child.props.id;

        return React.cloneElement(child, 
            key: id,
            // private attributes/methods that the Section component works with
            _selected: id === selectedId,
            _onSelect: this.onSelect
        );
    ,

    // when this section is selected, inform the parent Accordion component
    onSelect: function (id) 
        this.setState(selected: id);
    
);


module.exports = Accordion;

AccordionSection 组件看起来像这样:

const React = require('react');


const AccordionSection = React.createClass(

    render: function () 

        const className = 'accordion-section' + (this.props._selected ? ' selected' : '');

        return (
            <div className=className>
                <h3 onClick=this.onSelect>
                    this.props.title
                </h3>
                <div className='body'>
                    this.props.children
                </div>
            </div>
        );
    ,

    onSelect: function (e) 
        console.log('event:',e);
        // tell the parent Accordion component that this section was selected
        this.props._onSelect(this.props.id);
    
);



module.exports = AccordionSection;

一切正常,CSS 正常工作,但问题是 onClick 没有注册。所以点击手风琴元素什么都不做。有谁知道为什么 onClick 处理程序在这种情况下可能无法注册?

【问题讨论】:

JS 工作正常吗?是否有任何 JS 在客户端上工作? 我认为缺少的部分是在客户端上,一旦标记到达那里,我们需要进行更多实际绑定处理程序的 React 调用 【参考方案1】:

没有一个钩子会注册到 ReactDOMServer.RenderToString。如果你想在你的 react 组件上完成服务器端渲染 + 钩子,你可以将它捆绑在客户端(webpack、gulp 等),然后在服务器上也使用 ReactDOMServer.RenderToString。

这是帮助我完成此任务的博客文章: https://www.terlici.com/2015/03/18/fast-react-loading-server-rendering.html

【讨论】:

【参考方案2】:

React DOM 渲染到字符串仅将初始 HTML 作为字符串发送,没有任何 JS。 您还需要一个客户端反应路由器,它将根据它们的 react-id 将所需的 JS 处理程序附加到 HTML。 JS需要两边都运行。 用于快速启动的通用渲染样板。 https://github.com/erikras/react-redux-universal-hot-example 另一个和你类似的问题。 React.js Serverside rendering and Event Handlers

【讨论】:

以上是关于onClick 处理程序未向 ReactDOMServer.renderToString 注册的主要内容,如果未能解决你的问题,请参考以下文章

Amazon Cognito 未向我的应用程序用户发送 SMS 文本消息

数据流任务成功执行但未向 Excel 文件写入任何行

Firebase 未向设备中的电话号码发送 OTP

Testflight beta 未向外部测试人员发送电子邮件或推送通知

CloudWatch 中的 AWS Canary 未向服务报告

Google FCM 服务器:200 但未向手机发送通知