javascript - react 序列化组件从服务器发送

标签 javascript serialization reactjs ecmascript-6

我正在开发一个包含某种博客的网站。我想将我的个人博客文章写成 React 组件,以便它们可以包含其他组件。

博客文章如下所示,位于单独的文件中。

export default {
  name: 'test',
  title: 'Test',
  description: 'Description todo …',
  featureUrl: '/img/articles/test.jpg',
  component: class extends React.Component{
    render() {
      return (
        <div>
          <p>Here goes the test article …</p>
          <p>Some more …</p>
          <p>Some more …</p>
          <p>Some more …</p>
        </div>
      );
    }
  }
};

该应用支持服务器渲染。在服务器上,文章被加载到 Flux 存储中,并可能根据路由呈现:例如博客列表或特定博客文章本身。

然后我想将 Flux 存储的状态发送到客户端,这会导致对象被序列化。由于无法序列化函数,因此组件丢失了。在客户端,我想从服务器获取状态。但那时我缺少组件。

处理这个问题的好策略是什么?

我看过 Yahoo has a library序列化也有功能,但这对我来说似乎有点老套。

我目前正在做的是导入组件中所有应该呈现文章的文章,并根据当前文章在 Flux 状态下呈现特定内容。

import * as articles from 'articles';
(...)
let component = articles[articleName].component;

这行得通,但实际上并不是我想要的。我希望该组件可以通过商店的状态获得。另一种选择是在客户端重新初始化存储,但这样一来,将状态从服务器发送到客户端就毫无意义了。

有没有更好的方法来处理这个问题?

我正在使用 Redux 作为 Flux 库。

最佳答案

您走在正确的轨道上,只是想序列化商店。

服务器渲染的基本思想是,当一个请求进入你的服务器时,你收集必要的数据(在你的例子中是一篇博客文章),用它创建一个 Redux 存储,然后将整个应用程序组件树渲染成一个字符串服务器端预填充了正确的状态。

这是一个使用 Redux 1.0.0 语法和 ES6 的 Node.js 服务器渲染方法的粗略示例:

const initialState = {
  post: getBlogPostById(id); // or however you get your data
};

const reducer = combineReducers(reducers);
const store = createStore(reducer, initialState);

const stateString = JSON.stringify(initialState);

const appString = React.renderToString(
  <Provider store={store}>
    {() => <App/>}
  </Provider>
);

现在您已将整个应用程序呈现为一个字符串,显示正确的状态为 appString,并将相同的数据也字符串化为 stateString,所以现在您只需要将它们渲染到您的模板中以准备发送给客户。使用像这样的 Handlebars 语法,

<body>
  <div id="app">{{{appString}}}</div>
  <script>window.INITIAL_STATE = {{{stateString}}}</script>
  <script src="/app.js"></script>
</body>

在此示例中,app.js 是您的串联 JS 代码,其中包含获取 stateString 数据所需的代码,用它重新创建相同的 Redux 存储,然后渲染相同的组件树。 React 足够聪明,可以在客户端初始化相同的组件树时有效地“重新水化”我们在服务器端创建的现有 DOM。所以你的客户端 JS 可能看起来像,

const reducer = combineReducers(reducers);
const store = createStore(reducer, window.INITIAL_STATE);

React.render(
  <Provider store={store}>
    {() => <App/>}
  </Provider>,
  document.getElementById('app')
);

顺便说一句,将组件作为 native 对象的属性与一些元数据一起导出的方式看起来不太符合习惯。通常 React 有一个“每个文件一个组件”的约定,然后你可以将元数据存储在某个地方的专用 JSON 文件中。将 UI 组件定义与数据结构分开可能有助于应用程序的架构,但 YMMV 当然...

关于javascript - react 序列化组件从服务器发送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31301666/

相关文章:

javascript - 如何让 Webstorm 识别我的 LESS 文件?

c# - 如何在 flex 中为 C# 后端序列化对象

java - 可靠地识别序列化 Java 对象的类

java - 使用 Genson 将映射转换为键值对

javascript - 无法在 firebase 重定向结果中使用 Redux props

javascript - CSS:每次为数字时钟刷新时,如何使跨度的大小不变

javascript - 如何在点击页面时保持事件链接点亮?

javascript - 如何查找 rowspan 中的所有行并为所有行设置一个类

reactjs - React Router 4 和 enzyme

reactjs - 如何在reactjs中不使用getFieldDecorator的情况下验证ant design formitems?