Skip to content

Commit

Permalink
fix(core): fix incorrect template rendering on mount/unmount (#1232)
Browse files Browse the repository at this point in the history
  • Loading branch information
kvet authored Jul 11, 2018
1 parent 7b213a1 commit cd03c72
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/dx-react-core/src/plugin-based/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export const POSITION_CONTEXT = 'dxcore_position_context';
export const TEMPLATE_HOST_CONTEXT = 'dxcore_templateHost_context';

export const RERENDER_TEMPLATE_EVENT = Symbol('rerenderTemplate');
export const RERENDER_TEMPLATE_SCOPE_EVENT = Symbol('rerenderTemplateScope');
export const UPDATE_CONNECTION_EVENT = Symbol('updateConnection');
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import * as PropTypes from 'prop-types';
import { shallowEqual } from '@devexpress/dx-core';
import { PLUGIN_HOST_CONTEXT, RERENDER_TEMPLATE_EVENT, TEMPLATE_HOST_CONTEXT } from './constants';
import { PLUGIN_HOST_CONTEXT, RERENDER_TEMPLATE_EVENT, TEMPLATE_HOST_CONTEXT, RERENDER_TEMPLATE_SCOPE_EVENT } from './constants';

export class TemplatePlaceholder extends React.Component {
constructor(props, context) {
Expand All @@ -13,6 +13,11 @@ export class TemplatePlaceholder extends React.Component {
this.forceUpdate();
}
},
[RERENDER_TEMPLATE_SCOPE_EVENT]: (name) => {
if (this.props.name === name) {
this.forceUpdate();
}
},
};
}
getChildContext() {
Expand Down
4 changes: 3 additions & 1 deletion packages/dx-react-core/src/plugin-based/template.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import * as PropTypes from 'prop-types';
import { PLUGIN_HOST_CONTEXT, POSITION_CONTEXT, RERENDER_TEMPLATE_EVENT } from './constants';
import { PLUGIN_HOST_CONTEXT, POSITION_CONTEXT, RERENDER_TEMPLATE_EVENT, RERENDER_TEMPLATE_SCOPE_EVENT } from './constants';

let globalTemplateId = 0;
export class Template extends React.PureComponent {
Expand All @@ -23,6 +23,7 @@ export class Template extends React.PureComponent {
},
};
pluginHost.registerPlugin(this.plugin);
pluginHost.broadcast(RERENDER_TEMPLATE_SCOPE_EVENT, name);
}
componentDidUpdate() {
const { [PLUGIN_HOST_CONTEXT]: pluginHost } = this.context;
Expand All @@ -31,6 +32,7 @@ export class Template extends React.PureComponent {
componentWillUnmount() {
const { [PLUGIN_HOST_CONTEXT]: pluginHost } = this.context;
pluginHost.unregisterPlugin(this.plugin);
pluginHost.broadcast(RERENDER_TEMPLATE_SCOPE_EVENT, this.props.name);
}
render() {
return null;
Expand Down
46 changes: 46 additions & 0 deletions packages/dx-react-core/src/plugin-based/template.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,50 @@ describe('Template', () => {

expect(tree.find('h1').text()).toBe('new');
});

it('should be rerendered when added', () => {
const Test = ({ showSecond }) => (
<PluginHost>
<Template name="root">
<h1>first</h1>
</Template>
{showSecond && (
<Template name="root">
<h1>second</h1>
</Template>
)}
</PluginHost>
);
Test.propTypes = {
showSecond: PropTypes.bool.isRequired,
};

const tree = mount(<Test showSecond={false} />);
tree.setProps({ showSecond: true });

expect(tree.find('h1').text()).toBe('second');
});

it('should be rerendered when removed', () => {
const Test = ({ showSecond }) => (
<PluginHost>
<Template name="root">
<h1>first</h1>
</Template>
{showSecond && (
<Template name="root">
<h1>second</h1>
</Template>
)}
</PluginHost>
);
Test.propTypes = {
showSecond: PropTypes.bool.isRequired,
};

const tree = mount(<Test showSecond />);
tree.setProps({ showSecond: false });

expect(tree.find('h1').text()).toBe('first');
});
});
80 changes: 80 additions & 0 deletions packages/dx-vue-core/src/plugin-based/template.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,84 @@ describe('Template', () => {
expect(wrapper.find('h1').text())
.toEqual('new');
});

it('should be rerendered when added', () => {
const Test = {
props: {
showSecond: {
type: Boolean,
},
},
render() {
return (
<DxPluginHost>
<DxTemplate name="root">
<h1>first</h1>
</DxTemplate>
{this.showSecond && (
<DxTemplate name="root">
<h1>second</h1>
</DxTemplate>
)}
</DxPluginHost>
);
},
};

const wrapper = mount({
data() {
return {
showSecond: false,
};
},
render() {
return (
<Test showSecond={this.showSecond} />
);
},
});
wrapper.setData({ showSecond: true });
expect(wrapper.find('h1').text())
.toEqual('second');
});

it('should be rerendered when removed', () => {
const Test = {
props: {
showSecond: {
type: Boolean,
},
},
render() {
return (
<DxPluginHost>
<DxTemplate name="root">
<h1>first</h1>
</DxTemplate>
{this.showSecond && (
<DxTemplate name="root">
<h1>second</h1>
</DxTemplate>
)}
</DxPluginHost>
);
},
};

const wrapper = mount({
data() {
return {
showSecond: true,
};
},
render() {
return (
<Test showSecond={this.showSecond} />
);
},
});
wrapper.setData({ showSecond: false });
expect(wrapper.find('h1').text())
.toEqual('first');
});
});

0 comments on commit cd03c72

Please sign in to comment.