diff --git a/packages/react-instantsearch/src/core/InstantSearch.js b/packages/react-instantsearch/src/core/InstantSearch.js
index a18e4bacc2..a50ec6a94c 100644
--- a/packages/react-instantsearch/src/core/InstantSearch.js
+++ b/packages/react-instantsearch/src/core/InstantSearch.js
@@ -100,7 +100,9 @@ class InstantSearch extends Component {
}
onWidgetsInternalStateUpdate(searchState) {
- searchState = this.onSearchStateChange(searchState);
+ searchState = this.aisManager.transitionState(searchState);
+
+ this.onSearchStateChange(searchState);
if (!this.isControlled) {
this.aisManager.onExternalStateUpdate(searchState);
@@ -108,13 +110,9 @@ class InstantSearch extends Component {
}
onSearchStateChange(searchState) {
- searchState = this.aisManager.transitionState(searchState);
-
if (this.props.onSearchStateChange) {
this.props.onSearchStateChange(searchState);
}
-
- return searchState;
}
onSearchForFacetValues(searchState) {
diff --git a/packages/react-instantsearch/src/core/createConnector.js b/packages/react-instantsearch/src/core/createConnector.js
index 8c06cd296a..c2ac65119c 100644
--- a/packages/react-instantsearch/src/core/createConnector.js
+++ b/packages/react-instantsearch/src/core/createConnector.js
@@ -106,7 +106,13 @@ export default function createConnector(connectorDesc) {
// Since props might have changed, we need to re-run getSearchParameters
// and getMetadata with the new props.
this.context.ais.widgetsManager.update();
- this.context.ais.onSearchStateChange(this.context.ais.store.getState().widgets);
+ if (connectorDesc.transitionState) {
+ this.context.ais.onSearchStateChange(connectorDesc.transitionState(
+ nextProps,
+ this.context.ais.store.getState().widgets,
+ this.context.ais.store.getState().widgets,
+ ));
+ }
}
}
}
diff --git a/packages/react-instantsearch/src/core/createConnector.test.js b/packages/react-instantsearch/src/core/createConnector.test.js
index 02f9795c81..418debe005 100644
--- a/packages/react-instantsearch/src/core/createConnector.test.js
+++ b/packages/react-instantsearch/src/core/createConnector.test.js
@@ -215,12 +215,14 @@ describe('createConnector', () => {
const getSearchParameters = jest.fn(() => {
});
const onSearchStateChange = jest.fn();
+ const transitionState = jest.fn();
const update = jest.fn();
const Dummy = jest.fn(() => null);
const Connected = createConnector({
displayName: 'CoolConnector',
getProvidedProps,
getSearchParameters,
+ transitionState,
getId,
})(Dummy);
const wrapper = mount(, {
@@ -240,11 +242,14 @@ describe('createConnector', () => {
});
expect(onSearchStateChange.mock.calls.length).toBe(0);
expect(update.mock.calls.length).toBe(0);
+ expect(transitionState.mock.calls.length).toBe(0);
wrapper.setProps({hello: 'there', another: ['one', 'two']});
expect(onSearchStateChange.mock.calls.length).toBe(1);
+ expect(transitionState.mock.calls.length).toBe(1);
expect(update.mock.calls.length).toBe(1);
wrapper.setProps({hello: 'there', another: ['one', 'two']});
expect(onSearchStateChange.mock.calls.length).toBe(1);
+ expect(transitionState.mock.calls.length).toBe(1);
expect(update.mock.calls.length).toBe(1);
});
});
@@ -338,11 +343,13 @@ describe('createConnector', () => {
});
it('calls update when props change', () => {
+ const transitionState = jest.fn();
const Connected = createConnector({
displayName: 'CoolConnector',
getProvidedProps: () => null,
getMetadata: () => null,
getId,
+ transitionState,
})(() => null);
const update = jest.fn();
const onSearchStateChange = jest.fn();
@@ -362,17 +369,53 @@ describe('createConnector', () => {
}});
expect(update.mock.calls.length).toBe(0);
expect(onSearchStateChange.mock.calls.length).toBe(0);
+ expect(transitionState.mock.calls.length).toBe(0);
wrapper.setProps({hello: 'you'});
expect(update.mock.calls.length).toBe(1);
expect(onSearchStateChange.mock.calls.length).toBe(1);
+ expect(transitionState.mock.calls.length).toBe(1);
+ });
+
+ it('dont trigger onSearchStateChange when props change and the component has no transitionState function', () => {
+ const Connected = createConnector({
+ displayName: 'CoolConnector',
+ getProvidedProps: () => null,
+ getMetadata: () => null,
+ getId,
+ })(() => null);
+ const update = jest.fn();
+ const onSearchStateChange = jest.fn();
+ const props = {hello: 'there'};
+ const wrapper = mount(, {
+ context: {
+ ais: {
+ store: {
+ getState: () => ({}),
+ subscribe: () => null,
+ },
+ widgetsManager: {
+ registerWidget: () => null,
+ update,
+ },
+ onSearchStateChange,
+ },
+ },
+ });
+ expect(update.mock.calls.length).toBe(0);
+ expect(onSearchStateChange.mock.calls.length).toBe(0);
+ wrapper.setProps({hello: 'you'});
+ expect(update.mock.calls.length).toBe(1);
+ expect(onSearchStateChange.mock.calls.length).toBe(0);
});
it('dont update when props dont change', () => {
+ const transitionState = jest.fn();
const Connected = createConnector({
displayName: 'CoolConnector',
getProvidedProps: () => null,
getMetadata: () => null,
getId,
+ transitionState,
})(() => null);
const onSearchStateChange = jest.fn();
const update = jest.fn();
@@ -392,9 +435,11 @@ describe('createConnector', () => {
}});
expect(onSearchStateChange.mock.calls.length).toBe(0);
expect(update.mock.calls.length).toBe(0);
+ expect(transitionState.mock.calls.length).toBe(0);
wrapper.setProps({hello: 'there'});
expect(onSearchStateChange.mock.calls.length).toBe(0);
expect(update.mock.calls.length).toBe(0);
+ expect(transitionState.mock.calls.length).toBe(0);
});
it('unregisters itself on unmount', () => {