Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js: How to serialize/deserialize a React component?

I would like to serialize a React element (an instance of React component given props) and deserialize it elsewhere. Why you ask? I would like to be able to send the class from one process over stdout and render it in another process. I also want the rendered component to be interactive, so simply using ReactDOM.renderToString() will not suffice...

What I've tried:

  • Serializing it as a string and using eval() to deserialize it
  • Using a custom replacer and reviver functions for JSON.stringify() and JSON.parse() respectively

MyReactComponent.toString() returns:

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

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

which doesn't contain any of the methods unique to my component (such as render() or constructor()).

See this example code in JS Bin: http://jsbin.com/febuzupicu/edit?js,console,output

like image 572
senornestor Avatar asked Jan 29 '16 20:01

senornestor


2 Answers

Take a look at react-serialize. This package allows you to serialize react components into JSON strings and back.

like image 74
pravdomil Avatar answered Sep 28 '22 15:09

pravdomil


I've looked around extensively, haven't found anything.

I'm currently writing my own hydrate/dehydrate that converts react components into arrays of arguments to be passed in recursively to React.createElement(). I think that's the only way of doing it reliably. I'll probably make a small library for it.

In theory, perhaps one could use React.renderToString(), and pass around the string? But then you'd be using dangerouslySetInnerHtml... :\

Another update:

Here's the library: https://github.com/finetype/react-serialize

It has limitations, and it isn't the prettiest code I've ever written, but it also has decent test coverage. It was quite a bit harder to write than I expected, and in the end I sacrificed some much-desired functionality to just get something consistent. Hopefully those will be improved over time, and pull requests are welcome.

But it works. :)

Edit: After going way down this route (actually added a ton of functionality to that code that I didn't add to the repo because I didn't add sufficient test coverage), we ended up deciding it was a rabbit hole of a problem that should only be used for fairly simple use cases, and that our use case introduced enough complexity that it became too much to be worth the cognitive load it added to the code. I'd caution someone from going down this route.

like image 43
Kyle Baker Avatar answered Sep 28 '22 16:09

Kyle Baker