Skip to content

Commit 49bfeca

Browse files
authored
fix(transformData): always call transformData (#1555)
Event when data does not changes, we now call transformData, so that if the transformedData changes, there will be a new render. fixes #1538
1 parent e4d88e0 commit 49bfeca

File tree

6 files changed

+26
-50
lines changed

6 files changed

+26
-50
lines changed

src/components/RefinementList/__tests__/RefinementList-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ describe('RefinementList', () => {
235235

236236
// When
237237
const root = shallowRender(props);
238-
const actual = root.find('Template').filter({templateKey: 'show-more-inactive'});
238+
const actual = root.find('[templateKey="show-more-inactive"]');
239239

240240
// Then
241241
expect(actual.length).toEqual(1);

src/components/Template.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import hogan from 'hogan.js';
88

99
import isEqual from 'lodash/isEqual';
1010

11-
class Template extends React.Component {
11+
export class Template extends React.Component {
1212
shouldComponentUpdate(nextProps) {
1313
return !isEqual(this.props.data, nextProps.data) || this.props.templateKey !== nextProps.templateKey;
1414
}
@@ -22,7 +22,7 @@ class Template extends React.Component {
2222
templateKey: this.props.templateKey,
2323
compileOptions,
2424
helpers: this.props.templatesConfig.helpers,
25-
data: transformData(this.props.transformData, this.props.templateKey, this.props.data),
25+
data: this.props.data,
2626
});
2727

2828
if (content === null) {
@@ -137,4 +137,15 @@ function transformHelpersToHogan(helpers, compileOptions, data) {
137137
);
138138
}
139139

140-
export default Template;
140+
// Resolve transformData before Template, so transformData is always called
141+
// even if the data is the same. Allowing you to dynamically inject conditions in
142+
// transformData that will force re-rendering
143+
const withTransformData =
144+
TemplateToWrap =>
145+
props =>
146+
<TemplateToWrap
147+
{...props}
148+
data={transformData(props.transformData, props.templateKey, props.data)} // eslint-disable-line react/prop-types
149+
/>;
150+
151+
export default withTransformData(Template);

src/components/__tests__/Template-test.js

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import React from 'react';
44
import ReactDOM from 'react-dom';
55
import expect from 'expect';
66
import TestUtils from 'react-addons-test-utils';
7-
import Template from '../Template';
7+
import TemplateWithTransformData, {Template} from '../Template';
88
import sinon from 'sinon';
99
import expectJSX from 'expect-jsx';
1010
expect.extend(expectJSX);
@@ -120,11 +120,10 @@ describe('Template', () => {
120120
},
121121
});
122122

123-
renderer.render(<Template {...props} />);
123+
renderer.render(<TemplateWithTransformData {...props} />);
124124

125125
const out = renderer.getRenderOutput();
126-
const content = 'it supports transformData';
127-
const expectedJSX = <div dangerouslySetInnerHTML={{__html: content}}></div>;
126+
const expectedJSX = <Template {...props} data={{feature: 'transformData'}} />;
128127

129128
expect(out).toEqualJSX(expectedJSX);
130129
});
@@ -144,7 +143,7 @@ describe('Template', () => {
144143
},
145144
});
146145

147-
renderer.render(<Template {...props} />);
146+
renderer.render(<TemplateWithTransformData {...props} />);
148147
expect(called).toBe(true);
149148
});
150149

@@ -165,7 +164,7 @@ describe('Template', () => {
165164
},
166165
});
167166

168-
renderer.render(<Template {...props} />);
167+
renderer.render(<TemplateWithTransformData {...props} />);
169168
expect(called).toBe(true);
170169
});
171170

@@ -177,7 +176,7 @@ describe('Template', () => {
177176
});
178177

179178
expect(() => {
180-
renderer.render(<Template {...props} />);
179+
renderer.render(<TemplateWithTransformData {...props} />);
181180
}).toThrow('`transformData` must return a `object`, got `undefined`.');
182181
});
183182

@@ -191,7 +190,7 @@ describe('Template', () => {
191190
});
192191

193192
expect(() => {
194-
renderer.render(<Template {...props} />);
193+
renderer.render(<TemplateWithTransformData {...props} />);
195194
}).toNotThrow();
196195
});
197196

@@ -203,7 +202,7 @@ describe('Template', () => {
203202
});
204203

205204
expect(() => {
206-
renderer.render(<Template {...props} />);
205+
renderer.render(<TemplateWithTransformData {...props} />);
207206
}).toThrow('`transformData` must return a `object`, got `boolean`.');
208207
});
209208
});

src/decorators/__tests__/headerFooter-test.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ describe('headerFooter', () => {
6464
const out = render(defaultProps);
6565
// Then
6666
const templateProps = {
67-
data: {},
67+
data: undefined,
6868
templateKey: 'header',
6969
transformData: null,
7070
templates: {
@@ -90,7 +90,7 @@ describe('headerFooter', () => {
9090
const out = render(defaultProps);
9191
// Then
9292
const templateProps = {
93-
data: {},
93+
data: undefined,
9494
templateKey: 'footer',
9595
transformData: null,
9696
templates: {
@@ -118,7 +118,7 @@ describe('headerFooter', () => {
118118
footer: 'yo footer',
119119
};
120120
templateProps = {
121-
data: {},
121+
data: undefined,
122122
transformData: null,
123123
templates: {
124124
header: 'yo header',

src/widgets/refinement-list/__tests__/refinement-list-test.js

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
/* eslint-env mocha */
22

3-
import React from 'react';
43
import expect from 'expect';
54
import sinon from 'sinon';
65

7-
import {createRenderer} from 'react-addons-test-utils';
8-
96
import expectJSX from 'expect-jsx';
107
expect.extend(expectJSX);
118

129
import refinementList from '../refinement-list.js';
13-
import Template from '../../../components/Template.js';
14-
import createHelpers from '../../../lib/createHelpers.js';
15-
import defaultTemplates from '../defaultTemplates.js';
1610

1711
describe('refinementList()', () => {
1812
let autoHideContainer;
@@ -21,8 +15,6 @@ describe('refinementList()', () => {
2115
let options;
2216
let widget;
2317
let ReactDOM;
24-
const renderer = createRenderer();
25-
const helpers = createHelpers('en-US');
2618

2719
beforeEach(() => {
2820
container = document.createElement('div');
@@ -187,17 +179,6 @@ describe('refinementList()', () => {
187179
createURL = () => '#';
188180
});
189181

190-
it('formats counts', () => {
191-
const props = {
192-
templatesConfig: {helpers},
193-
templates: defaultTemplates,
194-
};
195-
renderer.render(<Template data={{count: 1000}} {...props} templateKey="item" />);
196-
const out = renderer.getRenderOutput();
197-
// eslint-disable-next-line max-len
198-
expect(out).toEqualJSX(<div dangerouslySetInnerHTML={{__html: '<label class="">\n <input type="checkbox" class="" value="" />\n <span class="">1,000</span>\n</label>'}} />);
199-
});
200-
201182
context('cssClasses', () => {
202183
it('should call the component with the correct classes', () => {
203184
// Given

src/widgets/toggle/implementations/__tests__/currentToggle-test.js

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,13 @@ import React from 'react';
44
import expect from 'expect';
55
import sinon from 'sinon';
66

7-
import {createRenderer} from 'react-addons-test-utils';
8-
97
import currentToggle from '../currentToggle.js';
108
import defaultTemplates from '../../defaultTemplates.js';
11-
import Template from '../../../../components/Template';
129

1310
import expectJSX from 'expect-jsx';
1411
expect.extend(expectJSX);
15-
import createHelpers from '../../../../lib/createHelpers.js';
1612

1713
describe('currentToggle()', () => {
18-
const helpers = createHelpers('en-US');
19-
const renderer = createRenderer();
20-
2114
context('good usage', () => {
2215
let ReactDOM;
2316
let containerNode;
@@ -102,14 +95,6 @@ describe('currentToggle()', () => {
10295
expect(ReactDOM.render.secondCall.args[1]).toEqual(containerNode);
10396
});
10497

105-
it('formats counts', () => {
106-
templateProps.templatesConfig = {helpers};
107-
renderer.render(<Template data={{count: 1000}} {...templateProps} templateKey="item" />);
108-
const out = renderer.getRenderOutput();
109-
// eslint-disable-next-line max-len
110-
expect(out).toEqualJSX(<div dangerouslySetInnerHTML={{__html: '<label class="">\n <input type="checkbox" class="" value="" />\n <span class="">1,000</span>\n</label>'}} />);
111-
});
112-
11398
it('understands cssClasses', () => {
11499
results = {
115100
hits: [{Hello: ', world!'}],

0 commit comments

Comments
 (0)