@@ -236,9 +236,16 @@ var ReactRailsUJS = {
236
236
// This attribute holds which method to use between: ReactDOM.hydrate, ReactDOM.render
237
237
RENDER_ATTR : 'data-hydrate' ,
238
238
239
+ // A unique identifier to identify a node
240
+ CACHE_ID_ATTR : "data-react-cache-id" ,
241
+
242
+ TURBOLINKS_PERMANENT_ATTR : "data-turbolinks-permanent" ,
243
+
239
244
// If jQuery is detected, save a reference to it for event handlers
240
245
jQuery : ( typeof window !== 'undefined' ) && ( typeof window . jQuery !== 'undefined' ) && window . jQuery ,
241
246
247
+ components : { } ,
248
+
242
249
// helper method for the mount and unmount methods to find the
243
250
// `data-react-class` DOM elements
244
251
findDOMNodes : function ( searchSelector ) {
@@ -304,6 +311,8 @@ var ReactRailsUJS = {
304
311
var propsJson = node . getAttribute ( ujs . PROPS_ATTR ) ;
305
312
var props = propsJson && JSON . parse ( propsJson ) ;
306
313
var hydrate = node . getAttribute ( ujs . RENDER_ATTR ) ;
314
+ var cacheId = node . getAttribute ( ujs . CACHE_ID_ATTR ) ;
315
+ var turbolinksPermanent = node . hasAttribute ( ujs . TURBOLINKS_PERMANENT_ATTR ) ;
307
316
308
317
if ( ! constructor ) {
309
318
var message = "Cannot find component: '" + className + "'"
@@ -312,13 +321,21 @@ var ReactRailsUJS = {
312
321
}
313
322
throw new Error ( message + ". Make sure your component is available to render." )
314
323
} else {
324
+ let component = this . components [ cacheId ] ;
325
+ if ( component === undefined ) {
326
+ component = React . createElement ( constructor , props ) ;
327
+ if ( turbolinksPermanent ) {
328
+ this . components [ cacheId ] = component ;
329
+ }
330
+ }
331
+
315
332
if ( hydrate && typeof ReactDOM . hydrate === "function" ) {
316
- ReactDOM . hydrate ( React . createElement ( constructor , props ) , node ) ;
333
+ component = ReactDOM . hydrate ( component , node ) ;
317
334
} else {
318
- ReactDOM . render ( React . createElement ( constructor , props ) , node ) ;
335
+ component = ReactDOM . render ( component , node ) ;
319
336
}
320
337
}
321
- }
338
+ }
322
339
} ,
323
340
324
341
// Within `searchSelector`, find nodes which have React components
@@ -422,13 +439,13 @@ module.exports = {
422
439
module . exports = {
423
440
// Turbolinks 5+ got rid of named events (?!)
424
441
setup : function ( ujs ) {
425
- ujs . handleEvent ( 'turbolinks:load' , ujs . handleMount )
426
- ujs . handleEvent ( 'turbolinks:before-render' , ujs . handleUnmount )
442
+ ujs . handleEvent ( 'turbolinks:load' , ujs . handleMount ) ;
443
+ ujs . handleEvent ( 'turbolinks:before-render' , ujs . handleMount ) ;
427
444
} ,
428
445
429
446
teardown : function ( ujs ) {
430
- ujs . removeEvent ( 'turbolinks:load' , ujs . handleMount )
431
- ujs . removeEvent ( 'turbolinks:before-render' , ujs . handleUnmount )
447
+ ujs . removeEvent ( 'turbolinks:load' , ujs . handleMount ) ;
448
+ ujs . removeEvent ( 'turbolinks:before-render' , ujs . handleMount ) ;
432
449
} ,
433
450
}
434
451
0 commit comments