2015-09-24 34 views
1

我有服務器這樣的代碼:如何處理具有同構React的子組件?

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

所以服務器呈現樣樣精。然後,無論我嘗試什麼,我都會收到關於我如何處理孩子序列化以及在瀏覽器中重新使用時的各種警告:React.render(App(window.PROPS.Layout), document.getElementById('content'));

我的很多嘗試讓React抱怨我應該使用createFragment。但是當我這樣做的時候,我仍然會得到一些我應該包裝它的錯誤。

我的目標是渲染帶有幾個孩子的Layout組件,並讓瀏覽器中的React知道下面的相同元素。許多嘗試也產生此錯誤:

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 

我的客戶端代碼是這樣的:

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

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

你的數據繼承了大量的子對象/字符串+標記標記,你應該將它們串聯在一起 – syarul

+0

@syarul當我把它們串在一起時,孩子們編碼,所以我看到頁面上的div而不是標記 –

回答

0

你不應該字符串化您的組件一樣,以服務爲您的客戶端。你應該再次呈現你的應用程序。串接的東西只應該是原始數據,如{id: 1, name: 'limelights'}

在服務器

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

和客戶端

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

具有同構的作用點上是相同的代碼服務器和客戶端上運行。

+0

那麼你說這些孩子的情況下,我應該有''寫在服務器和客戶端?我想我可以在服務器上指定孩子,並避免在客戶端重新鍵入 –

+0

另外PROPS.data已經是一個對象,因此不需要解析。該標記是有趣的,所以很容易錯過,如果我把字符串放在引號或不:) –

0

答案是我在做理論上錯誤的事情。

使服務器渲染像<Layout {...data} ><Comp1 /></Layout>將工作。然而,當瀏覽器投入使用時,它不會有兒童道具,你會失去Comp1。然後,我試圖通過像我的問題中的例子那樣的道具來傳遞孩子。真正的做法是簡單地讓服務器做<Layout {...data} ></Layout>

答案的真正關鍵是Layoutrender方法應該直接放置孩子。我可以在渲染中使用狀態(或道具,仍然可以找出語義差異)來確定孩子是否應該有所不同。

相關問題