【问题标题】:Node.js: How to serialize/deserialize a React component?Node.js:如何序列化/反序列化 React 组件?
【发布时间】:2016-05-07 17:40:59
【问题描述】:

我想序列化一个 React 元素(给定 props 的一个 React 组件实例)并在其他地方反序列化它。你为什么问?我希望能够通过标准输出从一个进程发送类并将其呈现在另一个进程中。我还希望渲染的组件是交互式的,所以仅仅使用ReactDOM.renderToString() 是不够的……

我尝试过的:

  • 将其序列化为字符串并使用eval()对其进行反序列化
  • 分别为 JSON.stringify() 和 JSON.parse() 使用自定义替换器和恢复器函数

MyReactComponent.toString() 返回:

"function MyReactClass() {
    _classCallCheck(this, MyReactClass);

    _get(Object.getPrototypeOf(MyReactClass.prototype), 'constructor', this).apply(this, arguments);
}"

其中不包含我的组件独有的任何方法(例如render() 或constructor())。

在 JS Bin 中查看此示例代码:http://jsbin.com/febuzupicu/edit?js,console,output

【问题讨论】:

  • 不确定你的意思 RE renderToString - 一旦在客户端渲染和初始化,它仍然是交互式的。如果您在 store 中有状态(例如 redux),则无需担心序列化 react 组件 - 您只需要序列化 ​​store。当然组件实例中的任何状态都会丢失,但是你可以编写纯组件
  • 问题是目的地不存在React组件类,所以无法在目的地调用ReactDOM.render()。我试图弄清楚如何从目标访问 React 组件类,是否将其作为字符串从源(尚未工作)发送,将其保存到文件并从目的地(因为两个进程将在同一台机器上运行)等。
  • 你不能只发送整个文件,加载它并在接收端使用 eval 吗?
  • 你能提供一个具体的用例吗?通常不会在客户端之间共享组件的实例,只共享在别处创建新实例所需的数据。
  • 我正在构建一个 Atom 插件,允许开发人员编写代码并将结果可视化。我想允许临时可视化,因此可视化代码将在开发人员端编写并在插件端呈现。所有通信都发生在 console.log -> stdout,所以它是字符串。我认为将可视化代码序列化为字符串并反序列化(eval)并使用它来呈现交互式可视化效果会很好。

标签: javascript node.js serialization reactjs deserialization


【解决方案1】:

看看react-serialize。此包允许您将反应组件序列化为 JSON 字符串并返回。

【讨论】:

    【解决方案2】:

    我已经四处寻找,没有找到任何东西。

    我目前正在编写自己的水合物/脱水物,它将反应组件转换为参数数组,以递归方式传递给React.createElement()。我认为这是可靠地做到这一点的唯一方法。我可能会为它制作一个小型图书馆。

    理论上,也许可以使用React.renderToString(),并传递字符串?但是你会使用dangerouslySetInnerHtml...:\

    另一个更新:

    这里是图书馆:https://github.com/finetype/react-serialize

    它有局限性,它不是我写过的最漂亮的代码,但它也有不错的测试覆盖率。它比我预期的要难写,最后我牺牲了一些非常需要的功能来获得一致的东西。希望这些会随着时间的推移得到改进,欢迎提出拉取请求。

    但它有效。 :)

    编辑:在沿着这条路线走下去之后(实际上,我在代码中添加了大量功能,但我没有添加到存储库中,因为我没有添加足够的测试覆盖率),我们最终决定这是一个兔子洞一个应该只用于相当简单的用例的问题,并且我们的用例引入了足够的复杂性,以至于它变得太不值得它添加到代码中的认知负荷。我会提醒某人不要走这条路。

    【讨论】:

      【解决方案3】:

      回答我自己的问题:

      // If I stringify this
      JSON.stringify({
        type: `React.createClass({
          render: function() {
            return <span>{this.props.name}</span>
          }
        })`,
        props: {
          name: 'Jorge'
        }
      })
      
      // Then I am able to parse it and deserialize it into a React element
      let {type, props} = payload
      // In Node
      React.createElement(vm.runInNewContext(type, {React}), props)
      // Not in Node
      React.createElement(eval(type), props)
      

      【讨论】:

      • 一般来说,由于循环引用(这些家伙中还有很多丑陋的毛茸茸的内部逻辑),一个人不能 JSON.stringify React.createClass() 的输出。如果它在这种情况下有效,那么它要么现在已经过时,要么很简单,以至于它不会遇到任何非平凡示例所遇到的问题。它还使用 eval,我们真的很想避免。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-27
      • 2011-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多