Skip to content

Commit

Permalink
Merge pull request #4048 from dmitrage/may-the-force-be-with-you
Browse files Browse the repository at this point in the history
  • Loading branch information
marvinhagemeister committed Jun 19, 2023
2 parents d887539 + f1eed0e commit 523bbe9
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 7 deletions.
11 changes: 4 additions & 7 deletions src/diff/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,14 @@ export function diff(
}

if (
(!c._force &&
c.shouldComponentUpdate != null &&
!c._force &&
((c.shouldComponentUpdate != null &&
c.shouldComponentUpdate(
newProps,
c._nextState,
componentContext
) === false) ||
newVNode._original === oldVNode._original
newVNode._original === oldVNode._original)
) {
// More info about this here: https://gist.github.com/JoviDeCroock/bec5f2ce93544d2e6070ef8e0036e4e8
if (newVNode._original !== oldVNode._original) {
Expand All @@ -154,8 +154,6 @@ export function diff(
c._dirty = false;
}

// In cases of bailing due to strict-equality we have to reset force as well
c._force = false;
newVNode._dom = oldVNode._dom;
newVNode._children = oldVNode._children;
newVNode._children.forEach(vnode => {
Expand Down Expand Up @@ -188,6 +186,7 @@ export function diff(
c.context = componentContext;
c.props = newProps;
c._parentDom = parentDom;
c._force = false;

let renderHook = options._render,
count = 0;
Expand Down Expand Up @@ -255,8 +254,6 @@ export function diff(
if (clearProcessingException) {
c._pendingError = c._processingException = null;
}

c._force = false;
} else if (
excessDomChildren == null &&
newVNode._original === oldVNode._original
Expand Down
53 changes: 53 additions & 0 deletions test/browser/components.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2660,5 +2660,58 @@ describe('Components', () => {

expect(scratch.innerHTML).to.equal('<div>bar</div>');
});

it('should skip shouldComponentUpdate when called during render', () => {
let isSCUCalled = false;
class App extends Component {
shouldComponentUpdate() {
isSCUCalled = true;
return false;
}
render() {
const isUpdated = this.isUpdated;
if (!isUpdated) {
this.isUpdated = true;
this.forceUpdate();
}
return <div>Updated: {isUpdated ? 'yes' : 'no'}</div>;
}
}
render(<App />, scratch);
rerender();
expect(isSCUCalled).to.be.false;
expect(scratch.innerHTML).to.equal('<div>Updated: yes</div>');
});

it('should break through strict equality optimization', () => {
let isSCUCalled = false;

class Child extends Component {
componentDidMount() {
this.props.parent.forceUpdate();
this.forceUpdate();
this.isUpdated = true;
}
shouldComponentUpdate() {
isSCUCalled = true;
return false;
}
render() {
return <div>Updated: {this.isUpdated ? 'yes' : 'no'}</div>;
}
}

class App extends Component {
children = (<Child parent={this} />);
render() {
return this.children;
}
}

render(<App />, scratch);
rerender();
expect(isSCUCalled).to.be.false;
expect(scratch.innerHTML).to.equal('<div>Updated: yes</div>');
});
});
});

0 comments on commit 523bbe9

Please sign in to comment.