繁体   English   中英

使用redux进行服务器端渲染

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM