反应同构和初始数据
react isomorphic and initial data
我正在使用 React 和 nodejs 创建一个等同商店。
我的问题是如何在服务器端使用初始数据填充我的组件。
我知道如何用初始数据填充我的主页组件,我在“/”路由中获取数据并将它们作为道具传递给我的组件。但是其他路线呢?
我可以定义多个服务器端路由,但我的网站不再是 SPA。
我如何获得反应路由器客户端路由和在服务器端启动数据的好处?
redux 可以为你节省一些时间。或者您可以在服务器上计算状态并将其作为 json 通过应用程序的道具填充到您的状态存储中。
React router 很容易实现同构,但无论如何你都必须通过你的状态。
这是我的示例 index.jsx 与反应路由器 w/o redux:
"use strict";
import React from 'react';
import { render } from 'react-dom';
import { match, Router, browserHistory } from 'react-router';
const injectTapEventPlugin = require('react-tap-event-plugin');
injectTapEventPlugin();
//for dev tools
window.React = React;
const routes = require('./Routes.jsx');
const history = browserHistory;
match({history, routes}, (error, redirectLocation, renderProps) => {
render(<Router {...renderProps} />, document.getElementById('app'));
})
在 Routes.jsx 中你会发现像这样的东西:
"use strict";
const React = require('react');
import { Router, Route, Link, IndexRoute } from 'react-router'
const Layout = require("./components/Layout.jsx");
const Login = require("./components/Login.jsx");
const Home = require("./components/Home.jsx");
const NotFound = require("./components/NotFound.jsx");
const routes = (
<Route path="/" component={Layout}>
<IndexRoute component={Home}/>
<Route path="login" component={Login}/>
<Route path="*" component={NotFound}/>
</Route>
);
module.exports = routes;
我在服务器端将以下组件用于带有 react-router 的 SPA,在 ReactDOMServer.renderToString()
中传入位置道具和初始状态对象
参考:React-Router Server Rendering docs
import React, { Component } from 'react';
import { createStore, combineReducers } from 'redux';
import { Provider } from 'react-redux';
import reducers from '../reducers';
import routes from '../routes';
import { match, RoutingContext } from 'react-router';
export default class App extends Component {
constructor(props) {
super(props);
}
render() {
let reducer = combineReducers(reducers);
let store = createStore(reducer, this.props);
var component;
match({ routes, location: this.props.location }, function (error, redirectLocation, renderProps) {
if (error) {
component = <p>{error.message}</p>;
} else if (renderProps) {
component = <RoutingContext {...renderProps} />;
} else {
component = <p>404 not found</p>;
}
})
return (
<Provider store={store}>
{component}
</Provider>
)
}
}
这是一个现实生活中的同构应用程序 https://github.com/WebbyLab/itsquiz-wall,所有这些问题都已解决。
此处涵盖的数据填充问题https://github.com/WebbyLab/itsquiz-wall/blob/master/server/app.js
这是我关于处理同构问题的博文 - "The Pain and the Joy of creating isomorphic apps in ReactJS"
我正在使用 React 和 nodejs 创建一个等同商店。 我的问题是如何在服务器端使用初始数据填充我的组件。 我知道如何用初始数据填充我的主页组件,我在“/”路由中获取数据并将它们作为道具传递给我的组件。但是其他路线呢? 我可以定义多个服务器端路由,但我的网站不再是 SPA。 我如何获得反应路由器客户端路由和在服务器端启动数据的好处?
redux 可以为你节省一些时间。或者您可以在服务器上计算状态并将其作为 json 通过应用程序的道具填充到您的状态存储中。
React router 很容易实现同构,但无论如何你都必须通过你的状态。
这是我的示例 index.jsx 与反应路由器 w/o redux:
"use strict";
import React from 'react';
import { render } from 'react-dom';
import { match, Router, browserHistory } from 'react-router';
const injectTapEventPlugin = require('react-tap-event-plugin');
injectTapEventPlugin();
//for dev tools
window.React = React;
const routes = require('./Routes.jsx');
const history = browserHistory;
match({history, routes}, (error, redirectLocation, renderProps) => {
render(<Router {...renderProps} />, document.getElementById('app'));
})
在 Routes.jsx 中你会发现像这样的东西:
"use strict";
const React = require('react');
import { Router, Route, Link, IndexRoute } from 'react-router'
const Layout = require("./components/Layout.jsx");
const Login = require("./components/Login.jsx");
const Home = require("./components/Home.jsx");
const NotFound = require("./components/NotFound.jsx");
const routes = (
<Route path="/" component={Layout}>
<IndexRoute component={Home}/>
<Route path="login" component={Login}/>
<Route path="*" component={NotFound}/>
</Route>
);
module.exports = routes;
我在服务器端将以下组件用于带有 react-router 的 SPA,在 ReactDOMServer.renderToString()
中传入位置道具和初始状态对象参考:React-Router Server Rendering docs
import React, { Component } from 'react';
import { createStore, combineReducers } from 'redux';
import { Provider } from 'react-redux';
import reducers from '../reducers';
import routes from '../routes';
import { match, RoutingContext } from 'react-router';
export default class App extends Component {
constructor(props) {
super(props);
}
render() {
let reducer = combineReducers(reducers);
let store = createStore(reducer, this.props);
var component;
match({ routes, location: this.props.location }, function (error, redirectLocation, renderProps) {
if (error) {
component = <p>{error.message}</p>;
} else if (renderProps) {
component = <RoutingContext {...renderProps} />;
} else {
component = <p>404 not found</p>;
}
})
return (
<Provider store={store}>
{component}
</Provider>
)
}
}
这是一个现实生活中的同构应用程序 https://github.com/WebbyLab/itsquiz-wall,所有这些问题都已解决。
此处涵盖的数据填充问题https://github.com/WebbyLab/itsquiz-wall/blob/master/server/app.js
这是我关于处理同构问题的博文 - "The Pain and the Joy of creating isomorphic apps in ReactJS"