As you might already have noticed in the above code I don’t use React.render
to render the <BookList/>
component. Instead I’m using a utility wrapper called ReactContentRenderer
. The purpose of this module is to automatically unmount all react components rendered into the content container before loading a new page. This is critical in traditional single-page-applications to prevent memory leaks since React keeps references to all mounted components until they get unmounted from the DOM.
let nodes = []; const ReactContentRenderer = { unmountAll() { if (nodes.length === 0) { return; } nodes.forEach(node => React.unmountComponentAtNode(node)); nodes = []; }, render(element, container, callback) { if (container instanceof jQuery) { container = container.get(0); } React.render(element, container, callback); nodes.push(container); } }; $(function () { $('#content') .on('content-will-change', ReactContentRenderer.unmountAll); });
ReactContentRenderer
keeps a reference to all component nodes and listens on content-will-change
events to unmount those components before the html of the content container gets replaced via $('#content').html(html)
.
If you don’t unmount those components, React would never know that the underlying HTML does no longer exist. You can inspect all mounted components by using the React Dev Tools (browser extension) to manually assure that obsolete components are already unmounted.
I hope you’ve enjoyed this article. Don’t hesitate to share your feedback with me on Twitter or use the comments below. You might also be interested in reading my article about how to render React components on Java servers by utilizing the Java 8 Nashorn engine. You should also check out my React Samples repository on GitHub, containing a bunch of client-side React examples.