diff --git a/hooks/test/browser/useState.test.js b/hooks/test/browser/useState.test.js index e58552c472..d87c21d7fd 100644 --- a/hooks/test/browser/useState.test.js +++ b/hooks/test/browser/useState.test.js @@ -19,6 +19,7 @@ describe('useState', () => { }); afterEach(() => { + Component.prototype.shouldComponentUpdate = undefined; teardown(scratch); }); @@ -414,4 +415,64 @@ describe('useState', () => { expect(renders).to.equal(2); }); }); + + it('Works when we combine strict equality, signals bail and state settling', () => { + // In signals we bail when we are using no signals/computeds/.... + Component.prototype.shouldComponentUpdate = function ( + nextProps, + nextState + ) { + return false; + }; + let setA, setB; + + const fooContext = createContext(); + const barContext = createContext(); + + function FooProvider({ children }) { + const [a, _setA] = useState(0); + setA = _setA; + return {children}; + } + + function BarProvider({ children }) { + const [b, _setB] = useState(0); + setB = _setB; + return {children}; + } + + function Child() { + const a = useContext(fooContext); + const b = useContext(barContext); + return ( +

+ {a}-{b} +

+ ); + } + + function App() { + return ( + + + + + + ); + } + + render(, scratch); + expect(scratch.innerHTML).to.equal('

0-0

'); + + act(() => { + // We update A first so that we have a top-down render going on + setA(1); + // The update will bail at B, we don't want sCU to run because + // else we risk the state's _nextValue being settled too early + // and thus applying the update too early and bailing on the subsequent + // render due to the values already being applied. + setB(1); + }); + expect(scratch.innerHTML).to.equal('

1-1

'); + }); }); diff --git a/src/diff/index.js b/src/diff/index.js index ae75d62dc9..3b8e20ee2e 100644 --- a/src/diff/index.js +++ b/src/diff/index.js @@ -165,14 +165,14 @@ export function diff( } if ( + newVNode._original == oldVNode._original || (!c._force && c.shouldComponentUpdate != NULL && c.shouldComponentUpdate( newProps, c._nextState, componentContext - ) === false) || - newVNode._original == oldVNode._original + ) === false) ) { // More info about this here: https://gist.github.com/JoviDeCroock/bec5f2ce93544d2e6070ef8e0036e4e8 if (newVNode._original != oldVNode._original) {