diff --git a/package-lock.json b/package-lock.json
index 013d118..7a20d65 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "clear-render",
- "version": "0.1.18",
+ "version": "1.0.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/src/Comparator.js b/src/Comparator.js
index 42fb293..3071e2b 100644
--- a/src/Comparator.js
+++ b/src/Comparator.js
@@ -1,27 +1,55 @@
class Comparator {
constructor(logger) {
- this._renderCount = 0;
+ this._logger = logger;
+ this._instances = {};
+ }
- this._prevProps = null;
- this._prevState = null;
+ _registration(id) {
+ this._instances[id] = {
+ id,
+ renderCount: 0,
+ prevProps: null,
+ prevState: null,
+ };
+ }
- this._logger = logger;
+ _saveCall(props, state) {
+ const id = this._getInstanceId(props);
+ const instance = this._getInstance(id);
+
+ instance.renderCount += 1;
+ instance.prevState = state;
+ instance.prevProps = props;
+ }
+
+ _getInstanceId(props) {
+ return props.clearRenderId || null;
+ }
+
+ _getInstance(id) {
+ return this._instances[id];
}
processChanges(nextProps, nextState) {
- const isFirstRender = !this._renderCount;
- if (isFirstRender) {
- this._logger.printInit();
+ const id = this._getInstanceId(nextProps);
+ const instance = this._getInstance(id);
+
+ if (!instance) {
+ this._registration(id);
+ this._logger.printInit(id);
} else {
- const propsChanges = this._shallowCompare(this._prevProps, nextProps);
- const stateChanges = this._shallowCompare(this._prevState, nextState);
+ const propsChanges = this._shallowCompare(instance.prevProps, nextProps);
+ const stateChanges = this._shallowCompare(instance.prevState, nextState);
- this._logger.printComparisonsResults(this._renderCount, propsChanges, stateChanges);
+ this._logger.printComparisonsResults(
+ id,
+ instance.renderCount,
+ propsChanges,
+ stateChanges
+ );
}
- this._renderCount += 1;
- this._prevState = nextState;
- this._prevProps = nextProps;
+ this._saveCall(nextProps, nextState);
}
_shallowCompare(oldObj = {}, nextObj = {}) {
diff --git a/src/__tests__/patch.spec.js b/src/__tests__/patch.spec.js
index a763c55..1e7de5a 100644
--- a/src/__tests__/patch.spec.js
+++ b/src/__tests__/patch.spec.js
@@ -42,6 +42,8 @@ test('Checkbox, detect changed state', () => {
expect(fakeLogger.printInit.mock.calls.length).toBe(1);
expect(fakeLogger.printComparisonsResults.mock.calls.length).toBe(1);
expect(fakeLogger.printComparisonsResults.mock.calls[0]).toEqual([
+ null,
+ 1,
[],
[{ key: 'isChecked', nextValue: true, oldValue: false, type: 'boolean' }],
]);
@@ -68,6 +70,8 @@ test('Checkbox, detect changed props', () => {
expect(fakeLogger.printInit.mock.calls.length).toBe(1);
expect(fakeLogger.printComparisonsResults.mock.calls.length).toBe(1);
expect(fakeLogger.printComparisonsResults.mock.calls[0]).toEqual([
+ null,
+ 1,
[{ key: 'title', type: 'string', oldValue: 'ping', nextValue: 'pong' }],
[],
]);
@@ -75,6 +79,74 @@ test('Checkbox, detect changed props', () => {
expect(getByTestId('props-title').textContent).toBe('pong');
});
+test('Checkbox, should separate instances, detect changed props', () => {
+ // Arrange
+ const fakeLogger = {
+ printInit: jest.fn(),
+ printComparisonsResults: jest.fn(),
+ };
+ const comparator = new Comparator(fakeLogger);
+ const PatchedCheckbox = patch(Checkbox, comparator);
+
+ // Act
+ const { rerender } = render(
+
+
+
+
+ );
+
+ rerender(
+
+
+
+
+ );
+
+ // Assert
+ expect(fakeLogger.printInit.mock.calls.length).toBe(2);
+ expect(fakeLogger.printInit.mock.calls[0]).toEqual(['1']);
+ expect(fakeLogger.printInit.mock.calls[1]).toEqual(['2']);
+
+ expect(fakeLogger.printComparisonsResults.mock.calls.length).toBe(2);
+ expect(fakeLogger.printComparisonsResults.mock.calls[0]).toEqual([
+ '1',
+ 1,
+ [
+ {
+ key: 'title',
+ type: 'string',
+ oldValue: 'ping',
+ nextValue: 'pong',
+ },
+ ],
+ [],
+ ]);
+ expect(fakeLogger.printComparisonsResults.mock.calls[1]).toEqual([
+ '2',
+ 1,
+ [
+ {
+ key: 'title',
+ type: 'string',
+ oldValue: 'ping',
+ nextValue: 'bong',
+ },
+ ],
+ [],
+ ]);
+});
+
test('Counter, detect changed props re-render', () => {
// Arrange
const fakeLogger = {
@@ -95,6 +167,8 @@ test('Counter, detect changed props re-render', () => {
expect(fakeLogger.printInit.mock.calls.length).toBe(1);
expect(fakeLogger.printComparisonsResults.mock.calls.length).toBe(1);
expect(fakeLogger.printComparisonsResults.mock.calls[0]).toEqual([
+ null,
+ 1,
[{ key: 'title', type: 'string', oldValue: 'ping', nextValue: 'pong' }],
[],
]);
@@ -122,6 +196,72 @@ test('Counter, used hooks', () => {
expect(fakeLogger.printComparisonsResults.mock.calls.length).toBe(1);
});
+test('Counter, should separate instances, detect changed props', () => {
+ // Arrange
+ const fakeLogger = {
+ printInit: jest.fn(),
+ printComparisonsResults: jest.fn(),
+ };
+ const comparator = new Comparator(fakeLogger);
+ const PatchedCounter = patch(Counter, comparator);
+
+ // Act
+ const { rerender } = render(
+
+
+
+
+ );
+
+ rerender(
+
+
+
+
+ );
+
+ // Assert
+ expect(fakeLogger.printInit.mock.calls.length).toBe(2);
+ expect(fakeLogger.printComparisonsResults.mock.calls.length).toBe(2);
+
+ expect(fakeLogger.printComparisonsResults.mock.calls[0]).toEqual([
+ '1',
+ 1,
+ [
+ {
+ key: 'title',
+ type: 'string',
+ oldValue: 'ping',
+ nextValue: 'pong',
+ },
+ ],
+ [],
+ ]);
+ expect(fakeLogger.printComparisonsResults.mock.calls[1]).toEqual([
+ '2',
+ 1,
+ [
+ {
+ key: 'title',
+ type: 'string',
+ oldValue: 'ping',
+ nextValue: 'bong',
+ },
+ ],
+ [],
+ ]);
+});
+
test('Input, detect changed props re-render', () => {
// Arrange
const fakeLogger = {
@@ -147,6 +287,8 @@ test('Input, detect changed props re-render', () => {
expect(fakeLogger.printInit.mock.calls.length).toBe(1);
expect(fakeLogger.printComparisonsResults.mock.calls.length).toBe(1);
expect(fakeLogger.printComparisonsResults.mock.calls[0]).toEqual([
+ null,
+ 1,
[{ key: 'value', type: 'string', oldValue: '', nextValue: 'i type ...' }],
[],
]);
diff --git a/src/logger.js b/src/logger.js
index aa84f19..5283517 100644
--- a/src/logger.js
+++ b/src/logger.js
@@ -4,17 +4,25 @@ class Logger {
this._log = log;
}
- printInit() {
+ _getComponentLabel(id) {
+ const componentName = this._componentName;
+
+ if (!id) {
+ return componentName;
+ }
+
+ return componentName + ` [id: ${id}]`;
+ }
+
+ printInit(id) {
+ const componentLabel = this._getComponentLabel(id);
+
this._log.log(
'%c[clear-render] init for',
'color: #848d95;',
- this._componentName
- );
- this._log.log(
- '%c[clear-render] render',
- 'color: #848d95;',
- this._componentName
+ componentLabel
);
+ this._log.log('%c[clear-render] render', 'color: #848d95;', componentLabel);
}
_printChange(change) {
@@ -39,11 +47,13 @@ class Logger {
}
}
- printComparisonsResults(renderCount, propsChanges, stateChanges) {
+ printComparisonsResults(id, renderCount, propsChanges, stateChanges) {
+ const componentLabel = this._getComponentLabel(id);
+
this._log.group(
`%c[clear-render] re-render #${renderCount}`,
'color: #848d95;',
- this._componentName
+ componentLabel
);
this._printComparisonResult('props', propsChanges);
this._printComparisonResult('state', stateChanges);
@@ -63,7 +73,6 @@ class Logger {
changes.forEach(this._printChange.bind(this));
this._log.groupEnd();
}
-
}
export default Logger;