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
+ {a}-{b} +
+ ); + } + + function App() { + return ( +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) {