@@ -236,9 +236,16 @@ var ReactRailsUJS = {
236236 // This attribute holds which method to use between: ReactDOM.hydrate, ReactDOM.render
237237 RENDER_ATTR : 'data-hydrate' ,
238238
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+
239244 // If jQuery is detected, save a reference to it for event handlers
240245 jQuery : ( typeof window !== 'undefined' ) && ( typeof window . jQuery !== 'undefined' ) && window . jQuery ,
241246
247+ components : { } ,
248+
242249 // helper method for the mount and unmount methods to find the
243250 // `data-react-class` DOM elements
244251 findDOMNodes : function ( searchSelector ) {
@@ -304,6 +311,8 @@ var ReactRailsUJS = {
304311 var propsJson = node . getAttribute ( ujs . PROPS_ATTR ) ;
305312 var props = propsJson && JSON . parse ( propsJson ) ;
306313 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 ) ;
307316
308317 if ( ! constructor ) {
309318 var message = "Cannot find component: '" + className + "'"
@@ -312,13 +321,21 @@ var ReactRailsUJS = {
312321 }
313322 throw new Error ( message + ". Make sure your component is available to render." )
314323 } 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+
315332 if ( hydrate && typeof ReactDOM . hydrate === "function" ) {
316- ReactDOM . hydrate ( React . createElement ( constructor , props ) , node ) ;
333+ component = ReactDOM . hydrate ( component , node ) ;
317334 } else {
318- ReactDOM . render ( React . createElement ( constructor , props ) , node ) ;
335+ component = ReactDOM . render ( component , node ) ;
319336 }
320337 }
321- }
338+ }
322339 } ,
323340
324341 // Within `searchSelector`, find nodes which have React components
@@ -422,13 +439,13 @@ module.exports = {
422439module . exports = {
423440 // Turbolinks 5+ got rid of named events (?!)
424441 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 ) ;
427444 } ,
428445
429446 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 ) ;
432449 } ,
433450}
434451
0 commit comments