简体   繁体   English

如何使用同构React处理子组件?

[英]How to handle child components with isomorphic React?

I have server code like this: 我有这样的服务器代码:

var data = {
  scripts: scripts,
  children:[<Comp1 />, <Comp2 />, <Comp3 />]
};

// keeping smaller for easier example than reality
var markup = '';

markup += '<script type="text/javascript">' +
'var PROPS = {' +
  'Layout: ' + JSON.stringify(data) +
'};' +
'</script>';

markup += React.renderToString(
    <Layout {...data} ></Layout>
);

So the server renders everything fine. 因此,服务器可以使一切正常。 Then no matter what I try, I get all sorts of warnings about how I'm handling the children for serialization and re-use in the browser when I run: React.render(App(window.PROPS.Layout), document.getElementById('content')); 然后无论我做什么尝试,都会收到有关运行时如何处理子项进行序列化和在浏览器中重新使用的各种警告: React.render(App(window.PROPS.Layout), document.getElementById('content'));

Many of my attempts make React complain that I should be using createFragment. 我的许多尝试使React抱怨我应该使用createFragment。 But when I do that, I still get errors that I should be wrapping it. 但是当我这样做时,仍然出现错误,应该将其包装。

My goal is to render the Layout component, with several children, and have React in the browser know the same elements are below. 我的目标是呈现具有多个子代的Layout组件,并使浏览器中的React知道下面的相同元素。 Many attempts also yield this error: 许多尝试也会产生此错误:

Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
 (client) d=".1frk89jhyio.1"></div><div data-react
 (server) d=".1frk89jhyio.1"><div style="float:lef

My client code is this: 我的客户代码是这样的:

var React = require('react'),
    Layout = require('./components/layout');

React.render(<Layout {...PROPS.Layout} />, document.getElementById('content'));

You shouldn't stringify your components like that to serve for your client. 您不应该像这样为您的客户服务的组件字符串化。 You should just render you application again. 您应该只再次渲染您的应用程序。 Things to stringify should only be raw data like {id: 1, name: 'limelights'} . 要字符串化的内容只能是原始数据,例如{id: 1, name: 'limelights'}

On the server 在服务器上

React.renderToString(<Layout {...data} />);

and on the client 和在客户端上

var data = JSON.parse(window.PROPS.data);
React.render(<Layout {...data} />, document.body);

The point of having an isomorphic application is that the same code runs on both the server and the client. 具有同构应用程序的要点是,服务器和客户端上都将运行相同的代码。

The answer is that I was doing things the theoretical wrong way. 答案是,我在做事情的理论上是错误的。

Having the server render like <Layout {...data} ><Comp1 /></Layout> will work. 将服务器呈现为<Layout {...data} ><Comp1 /></Layout> However when the browser kicks in, it won't have children props and you'll lose Comp1 . 但是,当浏览器启动时,它将没有子道具,并且您会丢失Comp1 Then I had tried to pass children through in as props like the example in my question. 然后,我试图像我问题中的例子一样让孩子们作为道具通过。 The real way to do this is simply having the server do <Layout {...data} ></Layout> . 真正的方法是让服务器执行<Layout {...data} ></Layout>

The real key to the answer is that the render method of Layout should be placing the children directly. 答案的真正关键是Layoutrender方法应该直接放置子代。 I can use state (or props, still working out semantic differences) within render to determine if children should be different. 我可以在render中使用状态(或道具,仍在解决语义差异)来确定子代是否应该不同。

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

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