2016-01-09 2 views
0

Пожалуйста, помогите мне разобраться в моей проблеме.Реагирование на серверной стороне ReactJS

У меня есть следующие на сервере -side (Node.js):

var React = require('react'); 
var ReactDOMServer = require('react-dom/server'); 

var TestComponent = React.createClass({ 
    render : function() { 
    return <div>test</div> 
    } 
}); 

// express router callback.. 
function(req, res, next) { 
    res.send(ReactDOMServer.renderToString(TestComponent)); 
}; 

Пример ответа:

<div data-reactid=".2e2hyaaz0n4" data-react-сhecksum="1124798100">test</div> 

А на клиента -side :

ReactDOM.render(React.createElement(template), document.getElementById('container')); 

Я имею следующую ошибку в консоли браузера:

Uncaught Invariant Violation: Invalid tag: <div data-reactid=".2e2hyaaz0n4" data-react-checksum="1124798100">test</div> 

Любая помощь будет оценен по достоинству!

ответ

1

Если template содержит строку

'<div data-reactid=".2e2hyaaz0n4" data-react-сhecksum="1124798100">test</div>' 

, то это не совсем правильно. Вы никогда не сможете отображать простой HTML, как если бы это был JSX. Вместо этого вы должны включить обработанный сервером HTML как часть источника страницы при его рендеринге, а затем инициализировать приложение для реакции на стороне клиента, используя одинаковые реквизиты, используемые на сервере.

Так, например, с помощью шаблона двигателя EJS:

// In Express 

function(req, res, next) { 
    var reactHtml = ReactDOMServer.renderToString(<TestComponent />); 
    res.render('index.ejs', {reactOutput: reactHtml}); 
}; 
<!-- In a template somewhere --> 
<div id="container"><%- reactOutput %></div> 
// In a client-side JavaScript file 

var TestComponent = React.createClass({ 
    render : function() { 
    return <div>test</div> 
    } 
}); 

ReactDOM.render(<TestComponent />, document.getElementById('container')); 

См How to Implement Node + React Isomorphic JavaScript & Why it Matters для получения дополнительной информации.

+1

Проверьте, что https: // facebook.github.io/react/docs/top-level-api.html#reactdomserver.rendertostring Похоже, это должно быть возможно. –

+1

@OlegMeleshko Можете ли вы уточнить? Я не уверен, что вы подразумеваете под своим комментарием. –

+1

Если вы вызываете ReactDOM.render() на узле, у которого уже есть эта обработанная сервером разметка, React сохранит ее и только присоединяет обработчики событий, что позволит вам иметь очень эффективный опыт первой загрузки. –

0

Проблема с вашим кодом заключается в том, что вы отправляете только тег div без реального документа. Это означает, что на сервере вы должны написать что-то вроде этого:

function(req, res, next) { 
    const component = ReactDOMServer.renderToString(TestComponent); 

    const layout = `<!DOCTYPE html> 
    <html> 
     <head lang="en"> 
     <meta charSet="utf-8"/> 
     <title>Isomorphic app</title> 
     </head> 
     <body> 
     <div id="container">${component}</div> 
     </body> 
    </html>`; 

    res.send(layout); 
}; 

Также вы можете проверить this repo с примером простого изоморфного приложения.

+1

Нет, это не то, что я хочу. –

0

Вы пытаетесь установить компонент на элементе с идентификатором контейнера.

ReactDOM.render(React.createElement(template), document.getElementById('container')); 

Но вы пропустили, чтобы добавить элемент с идентификатором контейнера в компоненте оказанной от ServerSide.
Для этого используется шаблон, например Jade.

div(class="container") 

renderedHTMLString

Если и хотите, чтобы заменить все тело просто добавить клиентскую сторону.

ReactDOM.render(React.createElement(template), document.getElementsByTagName('body')[0]); 
Смежные вопросы