2016-01-29 16 views
7

Vorrei serializzare un elemento React (un'istanza del componente React dato puntelli) e deserializzare altrove. Perchè lo chiedi? Mi piacerebbe essere in grado di inviare la lezione da un processo su stdout e renderlo in un altro processo. Voglio anche la componente reso per essere interattivo, così semplicemente usando ReactDOM.renderToString() non sarà sufficiente ...Node.js: Come serializzare/deserializzare un componente React?

che cosa ho provato:

  • serializzazione come una stringa e l'utilizzo di eval() per deserializzare esso
  • utilizzando un sostituto del costume e funzioni reviver per JSON.stringify() e JSON.parse() rispettivamente

MyReactComponent.toString() rendimenti:

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

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

che non contiene nessuno dei metodi univoci per il mio componente (ad esempio render() o constructor()).

Vedi questo codice di esempio nel JS Bin: http://jsbin.com/febuzupicu/edit?js,console,output

+0

Non sei sicuro di cosa intendi con renderingToString: sarebbe comunque interattivo una volta visualizzato e reso disponibile sul client. Non devi preoccuparti di serializzare il componente che reagisce se hai il tuo stato in un negozio (ad es. Redux) - avresti solo bisogno di serializzare il negozio.Ovviamente qualsiasi stato solo nell'istanza del componente andrebbe perso, ma potreste scrivere componenti puri –

+0

Il problema è che la classe del componente React non esiste nella destinazione, quindi non sarei in grado di chiamare 'ReactDOM.render()' alla destinazione Sto cercando di capire come posso accedere alla classe del componente React dalla destinazione, sia che la stia inviando come una stringa dall'origine (che non ha ancora funzionato), salvandola in un file e richiedendo quel file dal destinazione (poiché entrambi i processi saranno in esecuzione sulla stessa macchina), ecc. – senornestor

+0

Non puoi semplicemente inviare l'intero file, caricarlo e utilizzare eval su di esso dal lato ricevente? –

risposta

0

Per rispondere alla mia domanda:

// 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) 
+2

Generalmente, non è possibile JSON.stringificare l'output di 'React.createClass()', a causa di riferimenti circolari (anche un sacco di logica interna pelosa infelice in corso in questi ragazzi). Se funziona in questo caso, è obsoleto o è così semplice da non incontrare problemi che non sia un esempio banale. Utilizza anche eval, che vorremmo davvero evitare. –

1

Ho guardato in giro ampiamente, non hanno trovato nulla.

Attualmente sto scrivendo il mio idrato/disidratazione che converte i componenti reagenti in matrici di argomenti da passare in modo ricorsivo a React.createElement(). Penso che sia l'unico modo per farlo in modo affidabile. Probabilmente farò una piccola libreria per questo.

In teoria, è possibile utilizzare React.renderToString() e passare la stringa? Ma poi si sarebbe utilizzando dangerouslySetInnerHtml ...: \

Un altro aggiornamento:

Ecco la biblioteca: https://github.com/finetype/react-serialize

ha dei limiti, e non è il codice più bella che abbia mai scritto , ma ha anche una copertura di prova decente. È stato un po 'più difficile scrivere di quanto mi aspettassi, e alla fine ho sacrificato alcune funzionalità tanto desiderate per ottenere qualcosa di coerente. Speriamo che quelli saranno migliorati nel tempo, e le richieste di pull sono benvenute.

Ma funziona. :)

Modifica: dopo aver percorso questa route (in realtà ho aggiunto un sacco di funzionalità a quel codice che non ho aggiunto al repository perché non ho aggiunto una copertura sufficiente per il test), abbiamo finito per decidere che era una tana di un problema che dovrebbe essere usato solo per casi d'uso abbastanza semplici, e che il nostro caso d'uso ha introdotto una complessità tale da diventare troppo per il valore del carico cognitivo aggiunto al codice. Eviterei a qualcuno di seguire questa strada.

Problemi correlati