From 7555eaec1103f9244082709b70f5333002e10134 Mon Sep 17 00:00:00 2001 From: Jonathan Ziller Date: Fri, 12 Apr 2019 17:18:06 +0200 Subject: [PATCH] fix timing issue with setting up store subscription inside a connected component; see issue 1226 (#1235) --- src/components/connectAdvanced.js | 2 +- test/components/connect.spec.js | 32 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/components/connectAdvanced.js b/src/components/connectAdvanced.js index 6169fcb9a..0678a8007 100644 --- a/src/components/connectAdvanced.js +++ b/src/components/connectAdvanced.js @@ -291,7 +291,7 @@ export default function connectAdvanced( }) // Our re-subscribe logic only runs when the store/subscription setup changes - useEffect(() => { + useIsomorphicLayoutEffect(() => { // If we're not subscribed to the store, nothing to do here if (!shouldHandleStateChanges) return diff --git a/test/components/connect.spec.js b/test/components/connect.spec.js index 9e8a3a9c6..b2bbe2a4d 100644 --- a/test/components/connect.spec.js +++ b/test/components/connect.spec.js @@ -1926,6 +1926,38 @@ describe('React', () => { expect(mapStateToProps).toHaveBeenCalledTimes(2) }) + + it('should not notify nested components after they are unmounted', () => { + @connect(state => ({ count: state })) + class Parent extends Component { + render() { + return this.props.count === 1 ? : null + } + } + + const mapStateToProps = jest.fn(state => ({ count: state })) + @connect(mapStateToProps) + class Child extends Component { + render() { + return
{this.props.count}
+ } + } + + const store = createStore((state = 0, action) => + action.type === 'INC' ? state + 1 : state + ) + rtl.render( + + + + ) + + expect(mapStateToProps).toHaveBeenCalledTimes(0) + store.dispatch({ type: 'INC' }) + expect(mapStateToProps).toHaveBeenCalledTimes(1) + store.dispatch({ type: 'INC' }) + expect(mapStateToProps).toHaveBeenCalledTimes(1) + }) }) describe('Custom context and store-as-prop', () => {