嗨,我是全新的反应。我试图通过React通用渲染将数据从服务器传递到客户端。但我现在好运。我仍然可以渲染HTML,但我无法通过this.props.data
访问数据这是我的代码
// server.js
app.get('*', (req, res) => {
match({
routes: (<Router>{routes}</Router>),
location: req.url
},
(err, redirect, renderProps) => {
if (err) {
return res.status(500).send(err.message);
} else if (redirect) {
return res.redirect(302, redirect.pathnam + redirect.search);
} else if (renderProps.components.some(component => component === NotFoundPage)) {
res.status(404);
}
let data = [
{
title: 'Godfather'
},
{
title: 'Godfather 2'
}
];
data = JSON.stringify(data);
const renderedApp = renderToString(
<DataWrapper data={data}>
<RouterContext {...renderProps} />
</DataWrapper>
);
res.render('index.ejs', {
renderedApp
});
});
});
// routes.js
import React from 'react';
import { Route, IndexRoute } from 'react-router';
import HomePage from './components/routes/HomePage';
import MovieDetailsPage from './components/routes/MovieDetailsPage';
import NotFoundPage from './components/routes/NotFoundPage';
import App from './components/app';
export {
NotFoundPage
};
export default (
<Route path="/">
<IndexRoute component={HomePage} />
<Route path="movie" component={MovieDetailsPage} />
<Route path="*" component={NotFoundPage} />
</Route>
);
// client.js
import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, browserHistory } from 'react-router';
import routes from './routes';
import DataWrapper from '../src/DataWrapper';
let data = [];
ReactDOM.render(
<DataWrapper data={data}>
<Router history={browserHistory} routes={routes} onUpdate={window.scrollTo(0, 0)}/>
</DataWrapper>,
document.getElementById('app')
);
// DataWrapper
import React, { Component } from 'react';
class DataWrapper extends Component {
getChildContext () {
return {
data: this.props.data
};
}
render () {
return this.props.children;
}
}
DataWrapper.childContextTypes = {
data: React.PropTypes.oneOfType([
React.PropTypes.object,
React.PropTypes.array
]).isRequired
};
export default DataWrapper;
// HomePage.js我要访问this.props.data
中的数据import React, { Component } from 'react';
export default class HomePage extends Component {
constructor(props) {
super(props);
this.state = {
data: this.props.data
};
}
render() {
return (
<div>
<h1>{this.state.data}</h1>
</div>
);
}
}
有人可以指出我正确的方向并尽可能地解释我做错了吗
谢谢
答案 0 :(得分:0)
您目前正在<style>
html{
background-color: gray;
}
</style>
渲染孩子,但您没有传递道具。
不确定这是否是执行此操作的最佳方式,但这是我如何获得道具和状态传递
DataWrapper
答案 1 :(得分:0)
在这种情况下,我建议使用Redux而不是编写自定义数据包装器。因为 Redux可以使事实成为唯一的来源,无论其处于哪个级别(父级或子级)以及页面的呈现位置(服务器或客户端),所有组件都可以引用。即使引入了更多的开销,它也可以帮助您使架构师更清晰。
这是我之前使用的一些伪代码:
// server.js
// configureStore will create a empty store here.
const store = configureStore();
// Then use store.setState or any middleware to prepopulate the store.
....
const jsx = (
<ReduxProvider store={store}>
<StaticRouter context={context} location={req.url}>
<App/>
</StaticRouter>
</ReduxProvider>
);
const html = '<!doctype html><html><head></head>
<body>
<script>
window.REDUX_DATA = ${ JSON.stringify(store.getState()) }
</script>
<div id="root">${ReactDOM.renderToString(jsx)}</div>
</body>
</html>'
res.send(html)
// client.js
const render = App => {
// configStore will create store in client side with initial state passed from server.
const store = configStore(window.REDUX_DATA);
return ReactDOM.hydrate(
<ReduxProvider store={store}>
<BrowserRouter>
<App/>
</BrowserRouter>
</ReduxProvider>,
document.getElementById('root')
);
};
// HomePage.js
class HomePage extends React.Component {
render() {
return (
<div>
this.props.foo.value
</div>
)
}
const mapStateToProps = (state) => ({foo: state.foo});
export default connect(mapStateToProps)(HomePage);
}