服务器端与REDX渲染

我有一个简单的应用程序与reactjs和redux构build。 作为即时开始学习REDX我有一些问题做服务器端渲染。

我到目前为止是…客户端App.js呈现应用程序组件。

render( <Provider store={store}> <App /> </Provider>, document.body ); 

应用程序组件:

 const App = () => ( <div> <SearchContainer /> <TodoContainer /> </div> ) 

如果两个项目都是容器,SearchContainer从input框中获取input,发起一个正在调度带有加载待办事项(来自远程rest服务)的消息的操作。

现在编号喜欢加载在服务器端的页面加载的待办事项,并显示一次页面显示。 我会怎么做呢? 有没有办法在页面实际显示之前不使用服务器端渲染和加载项目?

目前为止,route.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数组作为属性?

你不需要服务器端渲染。

解决您遇到的问题最常用的方法是从componentDidMount加载数据。 在返回此数据之前,您需要显示某些内容,例如微调器或短语,或者消息或空白页。 就是那样子。 你的应用程序不会是唯一一个加载指标…

然而,你也可以做的是在你发送页面之前抓取数据服务器端,然后 <script>标记中的页面和JSON.stringify的帮助将其发送下来。

 <script> window.initialData = { "myData": [ 1, 2, 3 ] }; </script> 

然后你可以使用它来初始化商店。 这使数据立即可用,并且不需要API端点。

 const store = createStore(reducer, window.initialData, applyMiddleware(...middleware)); 

您也可以使用这些相同的数据在服务器上进行渲染,但这并不是必需的。

最后,我想指出的是,您正在渲染到document.body ,这是一个坏主意,因为很多浏览器扩展和插件添加一个div或其他东西到DOM为他们自己的需要。 React和那些玩不好。 它期望控制它传递的元素。 最好是创build一个div然后渲染。

考虑如果你真的需要在待办事项应用程序的SSR。 主要的优点是改进了search引擎优化,你的应用程序准备好了一点(它已经呈现)。 如果它不会很重,可以跳过这个。

有没有办法在页面实际显示之前不使用服务器端渲染和加载项目?

是的,例如,您可以派发获取数据并将其推入componentWillMount Redux状态的操作。 在数据不存在的情况下,你可以渲染一些负载指示符。

那么,已经获得了一些反应,redux,nodejs和一些其他客户端和服务器端技术的经验,这是我发现,以及它如何为我工作。

react / redux应用程序中的服务器端渲染由几个步骤组成:1.将数据加载到服务器上2.将数据从服务器推送到客户端3.将数据加载到redux存储

这里是上传“redux-polyglot”组件的翻译小例子。

routes.js [句柄expression服务器请求]:

 //...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) }); } 

这里的“家”值是句柄模板名称,它具有:

 <script type="application/json" id="phrases"> {{{ phrases }}} </script> 

然后,应用程序的责任是从“短语”脚本标签加载数据,并使用多边形提供的function将其设置为默认语言。

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" }