From 57ebfd1b4617d453b9dc851b82186d80cd529e1a Mon Sep 17 00:00:00 2001 From: Matthieu Prat Date: Mon, 11 Dec 2017 16:25:13 +0100 Subject: [PATCH 1/2] chore: add .prettierrc --- .prettierrc | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .prettierrc diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..4a4b3d5 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +semi: false +trailingComma: all +printWidth: 80 +singleQuote: true From 57dc9178d0ce735ce647beb8e7fe8e8404b3bced Mon Sep 17 00:00:00 2001 From: Matthieu Prat Date: Mon, 11 Dec 2017 16:38:17 +0100 Subject: [PATCH 2/2] fix(connectObs): unsubscribe from observables when unmounting --- src/__tests__/connectObs.test.js | 24 +++++++++++++++++++++++ src/connectObs.js | 33 ++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/__tests__/connectObs.test.js b/src/__tests__/connectObs.test.js index 458fd19..07100d7 100644 --- a/src/__tests__/connectObs.test.js +++ b/src/__tests__/connectObs.test.js @@ -143,4 +143,28 @@ describe('connectObs', () => { ) expect(wrapper.equals(
)).toBeTruthy() }) + + it('unsubscribes from observables when the enhanced component is unmounted', () => { + const spy = jest.fn() + const spyUnsubscribe = observable => + Rx.Observable.create(observer => { + const subscription = observable.subscribe(observer) + return () => { + spy() + subscription.unsubscribe() + } + }) + + const Component = compose( + connectObs(({ props$ }) => ({ + foo: spyUnsubscribe(Rx.Observable.never()), + props: spyUnsubscribe(props$), + })), + )('div') + + const wrapper = shallow() + expect(spy).toHaveBeenCalledTimes(0) + wrapper.unmount() + expect(spy).toHaveBeenCalledTimes(2) + }) }) diff --git a/src/connectObs.js b/src/connectObs.js index 24b63c3..abce2cf 100644 --- a/src/connectObs.js +++ b/src/connectObs.js @@ -62,9 +62,11 @@ const connectObs = obsMapper => withObs(observables => { const nextProps$ = createObservable(observer => { const obsMap = obsMapper(observables) - checkObsMap(obsMap) - let props const obsProps = {} + const obsSubscriptions = [] + let props + + checkObsMap(obsMap) const update = () => { if (props) { @@ -84,23 +86,34 @@ const connectObs = obsMapper => const observable = obsConfig.toESObservable(obsMap[key]) checkObservable(observable, key) obsProps[key] = undefined - observable.subscribe({ + const subscription = observable.subscribe({ next(value) { obsProps[key] = value update() }, error: asyncThrow, }) + + obsSubscriptions.push(subscription) } }) - obsConfig.toESObservable(observables.props$).subscribe({ - next(nextProps) { - props = nextProps - update() - }, - error: asyncThrow, - }) + const propsSubscription = obsConfig + .toESObservable(observables.props$) + .subscribe({ + next(nextProps) { + props = nextProps + update() + }, + error: asyncThrow, + }) + + return () => { + propsSubscription.unsubscribe() + obsSubscriptions.forEach(subscription => { + subscription.unsubscribe() + }) + } }) return { props$: nextProps$ }