[英]Server side rendering with redux
我有一个使用reactjs和redux构建的简单应用程序。 由于我刚刚开始学习redux,我在服务器端渲染时遇到了一些问题。
到目前为止我所拥有的是... Client App.js渲染App组件。
render(
<Provider store={store}>
<App />
</Provider>,
document.body
);
一个App组件:
const App = () => (
<div>
<SearchContainer />
<TodoContainer />
</div>
)
如果两个项都是容器,则SearchContainer从输入框获取输入,触发一个动作,该动作将使用加载的todo`s(来自远程休息服务)调度消息。
现在我喜欢在服务器端的页面加载上加载那些todo,并在页面显示后显示它们。 我该怎么办? 有没有办法在页面实际显示之前不使用服务器端渲染和加载项目?
到目前为止,我到目前为止是routes.js文件:
const middleware = [ thunk ]
if (process.env.NODE_ENV !== 'production') {
middleware.push(createLogger())
}
const store = createStore(reducer,applyMiddleware(...middleware))
app.get('/', function(req, res) {
res.render('home',{
markup: ReactDOMServer.renderToString(
<Provider store={store}>
<App />
</Provider>
)
});
//Some code calling remote service goes here
这通常是加载和应用程序,但我如何将加载的数据推送到TodoContainer? 它应该是某种方式来分派消息,还是应该使用todos数组作为属性来初始化App组件?
您不需要服务器端渲染。
解决您遇到的问题的最常见方法是从componentDidMount
加载数据。 在返回此数据之前,您需要显示某些内容,例如微调器或笨蛋或消息或空白页。 就是那样子。 您的应用不会是唯一一个带有加载指示器的应用...
不过,你也可以做的,就是获取数据的服务器端,你发送的页面下来之前,和与页面的送下来<script>
标记和帮助JSON.stringify
。
<script>
window.initialData = {
"myData": [ 1, 2, 3 ]
};
</script>
然后你可以用它来初始化商店。 这使数据立即可用,并消除了对API端点的需求。
const store = createStore(reducer, window.initialData, applyMiddleware(...middleware));
您也可以使用相同的数据在服务器上进行渲染,但无论如何都不需要它。
最后,我想指出你正在渲染document.body
,这是一个坏主意,因为很多浏览器扩展和插件为了自己的需要在DOM中添加了div或其他东西。 React不适合那些。 它期望控制它传递的元素。 最好只创建一个div
并将其渲染成一个div
。
考虑一下你是否真的需要在todo app中使用SSR。 主要优点是改进了SEO,你的应用程序准备好了一点(它已经渲染)。 如果它不会很重,你可能想跳过它。
有没有办法在页面实际显示之前不使用服务器端渲染和加载项目?
是的,例如,您可以调度获取数据的操作并将其推送到componentWillMount
Redux状态。 在数据不存在之前,您可以渲染某些加载指示器的null
。
好吧,我已经获得了一些反应,redux,nodejs和其他一些客户端和服务器端技术的经验,这是我发现的以及它如何为我工作。
react / redux应用程序中的服务器端呈现包括以下几个步骤:1。在服务器上加载数据2.将数据从服务器推送到客户端3.将数据加载到redux存储
这是一个上传'redux-polyglot'组件翻译的小例子。
routes.js [处理快速服务器请求]:
//...all of your imports goes here
import en_phrases from './resources/phrases/en'
app.get('/', async function(req, res) {
const store = createStore(reducers, applyMiddleware(...whatevermiddlewareyouneed))
return res.render('home', {
markup: ReactDOMServer.renderToString(
<Provider store={store}>
<App/>
</Provider>
),
otherPreloadedStateThanPhrases: JSON.stringify(...anythingelse)
phrases: JSON.stringify(en_phrases)
});
}
这里的'home'值是把手模板名称,它具有:
<script type="application/json" id="phrases">
{{{ phrases }}}
</script>
然后,应用程序的职责是从“短语”脚本标记加载数据,并将其设置为具有多语言提供功能的默认语言。
app.js
const phrases = JSON.parse(document.getElementById('phrases').innerHTML);
const store = createStore(reducers, otherPreloadedStateThanPhrases, applyMiddleware(...middleware));
store.dispatch(setLanguage('en', phrases));
LoginContainer.js [从应用程序中使用的样本容器]
let LoginContainer = ({p}) => {
<span>{p.tc('login')}</span>
}
exports.LoginContainer = connect((state) => ()(translate(LoginContainer))
其中'login'是从服务器上的短语json加载的值:en.js
export default {
login: "Login"
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.