React.js服务器端渲染和事件处理程序

我正在学习使用react.js,并有一些问题使用事件处理程序。 最后的问题是:是否可以使用服务器端渲染并自动将事件处理程序发送到客户端?

这里是我的例子:我有一个index.jsx我渲染服务器端并发送到客户端

var React = require("react"); var DefaultLayout = require("./layout/default"); var LikeButton = React.createClass({ getInitialState: function() { return {liked: false}; }, handleClick: function(event) { this.setState({liked: !this.state.liked}); }, render: function() { var text = this.state.liked ? 'like' : 'haven\'t liked'; return ( <p onClick={this.handleClick}> You {text} this. Click to toggle. </p> ); } }); var IndexComponent = React.createClass({ render: function(){ return ( <DefaultLayout title={this.props.name}> <div> <h1>React Test</h1> </div> <div id="testButton"> <LikeButton/> </div> <script type="text/babel" src="/js/react.js"></script> </DefaultLayout> ) } }); 

但“喜欢button”没有任何交互。 为了让它做点击我必须添加这个代码客户端。

 var LikeButton = React.createClass({ getInitialState: function() { return {liked: false}; }, handleClick: function(event) { this.setState({liked: !this.state.liked}); }, render: function() { var text = this.state.liked ? 'like' : 'haven\'t liked'; return ( <p onClick={this.handleClick}> You {text} this. Click to toggle. </p> ); } }); ReactDOM.render( <LikeButton />, document.getElementById('testButton') ); 

我只是从react.js开始,也许我只是想念一些重要的概念。 但是为什么react.js不只是在呈现页面服务器端时创build代码(我现在必须手动添加到客户端)呢? 像这样,我有冗余的代码,感觉在更大的应用程序中这将会是一团糟。 至lessreact.js足够聪明,不能绘制两个LikeButton,而是将创build的服务器端“绑定”到客户端组件。

对于客户端交互式React应用程序,您也需要呈现应用程序客户端。 通常这个代码和你在服务器上运行的代码是一样的, 所以没有多余的代码 。 这只是相同的代码。 你可能会问自己,如果在客户端和服务器上渲染可能是矫枉过正,但从性能和search引擎优化的angular度来看,这是非常有道理的。

ReactDOMServer.renderToString(<MyApp foo={bar} />)基本上只是呈现一个带有标记的string。 那里没有JavaScript或任何魔法。 只是普通的旧HTML。 然而,渲染的标记有很多的React ID属性,稍后在客户端使用它来生成初始的虚拟DOM和附加事件。

当你在客户端再次渲染你的应用程序时,React不需要重绘整个应用程序,在服务器端渲染标记的同一个DOM元素上, 它只是创build一个新的虚拟DOM树,与最初的虚拟DOM树不同,并执行必要的DOM操作(如果有的话)。 虚拟DOM的这个概念是让React如此之快的原因。 在相同的过程中,您在应用程序中定义的任何事件侦听器都将附加到已经呈现的标记中。

所有这一切发生得非常快。 而且你有一个服务器端渲染页面的好处(可以caching在服务器上,使用Varnish或类似的东西),search引擎将抓取,用户不需要等待任何东西来看到最初的渲染,页面基本上适用于禁用JavaScript的用户。

这种行为是因为服务器端渲染是什么。 首先,你将不得不在客户端和服务器端运行完全相同的代码。 这就是所谓的同构应用程序。 一个在服务器和客户端上运行。
所以,在做ReactDOM.renderToString(<Component>)只有HTML呈现为一个string。 评估组件的渲染方法,并生成初始渲染所需的HTML。
当客户端运行相同的代码时,反应会查找呈现的HTML并在需要的位置附加JS。 React很聪明,它不会在客户端重新渲染所有东西。 只是评估代码,并确定所有附加的代码基于react-id每个DOM元素给出。 (如果你检查元素任何反应的应用程序,你会反应,ID)

现在有人可能会问,两次渲染同样的东西有什么好处?
并且答案被用户perceived loading time 。 对于禁用JS的用户也有一些最小的查看。

客户端呈现的应用
这是一个客户端提交的应用程序的工作原理。 (客户端也渲染了React应用程序)

客户端呈现应用

用户将只看到所有的骨架HTML,JS捆绑(通常很大),数据被提取和评估的内容。 这意味着用户将经常不得不盯着旋转器或加载屏幕一段时间,直到一切都加载。

同构应用程序(同时在客户端和服务器上运行)
同构应用程序如何工作,
服务器呈现的应用
在这种情况下,服务器通过评估组件来生成完整的 HTML。 用户将立即看到下载HTML的内容。 尽pipe一旦JS捆绑包也被下载和评估,应用程序将只能完全运行 。 所以JS必须运行在双方
因此,用户比以前更快地看到内容。 因此,感知加载时间的巨大减less。