Project

General

Profile

« Previous | Next » 

Revision b976723b

Added by Avi Sharvit almost 6 years ago

Fixes #23290 - Unmount components before dom-update

  • provide core `tfm.reactMounter.unmountComponents` function
  • unmount components before saving host and manually update the dom with
    jquery

View differences:

app/assets/javascripts/host_edit.js
clear_errors();
animate_progress();
// clean the dom from react components before replacing the dom-content
tfm.reactMounter.unmountComponents('#content');
$.ajax({
type:'POST',
url: url,
webpack/assets/javascripts/react_app/common/MountingService.js
export { default as registerReducer } from '../redux/reducers/registerReducer';
const mountedNodes = [];
let mountedNodesCache = [];
// In order to support turbolinks with react, need to
// unmount all root components before turbolinks do the unload
// TODO: remove it when migrating into (webpacker-react or react-rails)
document.addEventListener('page:before-unload', () => {
let node = mountedNodes.shift();
document.addEventListener('page:before-unload', () => unmountComponents());
while (node) {
ReactDOM.unmountComponentAtNode(node);
node = mountedNodes.shift();
const unmountComponentsByNodes = nodes =>
nodes.forEach(node => ReactDOM.unmountComponentAtNode(node));
/**
* Will unmount all react-components from the dom
* @param {string} selector unmount component inside the selector
* @return {number} amount of unmounted nodes
*/
export const unmountComponents = (selector) => {
const nodesToUnmount = [];
const nodesToKeep = [];
if (selector) {
const reactNode = document.querySelector(selector);
mountedNodesCache.forEach((node) => {
if (reactNode.contains(node)) {
nodesToUnmount.push(node);
} else {
nodesToKeep.push(node);
}
});
} else {
nodesToUnmount.push(...mountedNodesCache);
}
});
export function mount(component, selector, data) {
unmountComponentsByNodes(nodesToUnmount);
mountedNodesCache = nodesToKeep;
return nodesToUnmount.length;
};
export const mount = (component, selector, data) => {
const reactNode = document.querySelector(selector);
if (reactNode) {
......
reactNode,
);
mountedNodes.push(reactNode);
mountedNodesCache.push(reactNode);
} else {
// eslint-disable-next-line no-console
console.log(`Cannot find '${selector}' element for mounting the '${component}'`);
}
}
};

Also available in: Unified diff