我可以在服务器端渲染数据时将数据传递给反应组件,如:
app.get('/', function (req, res, next) {
var reactHtml = ReactDOMServer.renderToString(component({data}));
res.render('index.jade', {reactOutput: reactHtml});
});
现在我将其改为
server.js:
app.get('*', (req, res) => {
// match the routes to the url
match({ routes: routes, location: req.url }, (err, redirect, props) => {
props.data = {q:123};
const appHtml = ReactDOMServer.renderToString(routerContext(props));
res.render('index.jade', {reactOutput: appHtml});
})
});
路由器上下文
module.exports = React.createClass({
render: function(){return(<RouterContext {...this.props} />)}
});
和路线
module.exports = (
<Route path="/" component={App} {...this.props}>
<IndexRoute component={List}/>
<Route path="/about" component={About}/>
</Route>
);
App.jsx
var App = React.createClass({
render: function () {
console.log(this.props);
return (
<div id="app-root" className="container">
<Nav/>
<h1>{this.props.q}</h1>
{this.props.children}
<div className="Row">
<div className="footer col-lg-12"></div>
</div>
</div>
)
}
});
例如,我希望在我的App组件中从此点props.data = {q:123};
获取数据,但是当我在App组件渲染方法中console.log(this.data);
时,我已经获得了历史记录,位置等,但不是我的数据。无论如何,从server.js逻辑传递数据{q:123}
到组件(App或List或About)道具?
(让我们现在总是加载一些数据)
答案 0 :(得分:2)
您需要序列化数据并将其添加到服务器渲染中的页面,例如,如果您将其作为initialState
传递给根组件:
renderInitialState() {
const innerHtml = `window.__INITIAL_STATE__ = ${JSON.stringify(this.props.initialState)}`;
return <script dangerouslySetInnerHTML={{__html: innerHtml}} />;
}
所以:
<script>window.__INITIAL_STATE__ = JSON.stringify(yourObject);</script>
请注意,您似乎正在使用jade来渲染“shell”而不是React。所以同样的事情适用但是为玉模板做。
您通常会在<body>
的底部(但在您的应用js脚本上方)渲染它。
如果您在客户端状态下使用flux,则在创建商店时会传递此对象,例如对于redux:
const store = configureStore(window.__INITIAL_STATE__);
答案 1 :(得分:0)
你的props.data = {q:123};
无法在任何地方被调用,因为RouterContext不知道如何处理它。
传递给match
的回调函数的三个参数是:
undefined
。Location
对象,
undefined
否则 renderProps:如果路由匹配,则应传递给路由上下文的道具undefined
否则。
如果所有三个参数都是undefined
,则表示找不到与之匹配的路径
给定位置。
要了解您可以在此处添加console.dir的机制
match({ routes: routes, location: req.url }, (err, redirect, props) => {
console.dir(props);
const appHtml = ReactDOMServer.renderToString(routerContext(props));
res.render('index.jade', {reactOutput: appHtml});
})
});
console.dir(props.components)
会显示传递给渲染的所有组件。您还可以在此处创建新的react元素并将其推送到props.components
将数据传递到您的应用组件 ,没有商店
修改此函数以便能够检索数据,并使用新数据创建虚拟组件
routes.jsx
module.exports = function(serverData){
var Dummy= React.createClass({
render: function () {
return (
<div> customProps=serverData </div>
);}
});
return(
<Route path="/" component={App}>
<Route path='data' component={{PonyMan: Dummy}}
<IndexRoute component={List}/>
<Route path="/about" component={About}/>
</Route>
);
}
server.jsx:
app.get('*', (req, res) => {
myCustomData = 'I like ponies'
const routes = createRoutes(myCustomData); //from imported routes.jsx
match({ routes: routes, location: req.url }, (err, redirect, props) => {
const appHtml = ReactDOMServer.renderToString(routerContext(props));
res.render('index.jade', {reactOutput: appHtml});
})
});
App.js
var App = React.createClass({
render: function () {
return (
<div id="app-root" className="container">
<Nav/>
<h1>{this.props.main}</h1>//this now shows <div>I Like Ponies</div>
//this can still display other routes
{this.props.children}
<div className="Row">
<div className="footer col-lg-12"></div>
</div>
</div>
)
}
});
P.S。使用redux商店会更容易 检查这个项目,看一下使用服务器端渲染的react-router redux express mongoose项目的一个很好的例子 https://github.com/choonkending/react-webpack-node