Skip to content

Commit

Permalink
Invoke setState callbacks setup in componentWillMount (#3806)
Browse files Browse the repository at this point in the history
Fixes #556
  • Loading branch information
andrewiggins committed Nov 22, 2022
1 parent 4a37c99 commit d4089df
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 2 deletions.
3 changes: 1 addition & 2 deletions src/diff/index.js
Expand Up @@ -110,6 +110,7 @@ export function diff(

oldProps = c.props;
oldState = c.state;
c._vnode = newVNode;

// Invoke pre-render lifecycle methods
if (isNew) {
Expand Down Expand Up @@ -146,7 +147,6 @@ export function diff(
c.state = c._nextState;
// More info about this here: https://gist.github.com/JoviDeCroock/bec5f2ce93544d2e6070ef8e0036e4e8
if (newVNode._original !== oldVNode._original) c._dirty = false;
c._vnode = newVNode;
newVNode._dom = oldVNode._dom;
newVNode._children = oldVNode._children;
newVNode._children.forEach(vnode => {
Expand Down Expand Up @@ -178,7 +178,6 @@ export function diff(

c.context = componentContext;
c.props = newProps;
c._vnode = newVNode;
c._parentDom = parentDom;

let renderHook = options._render,
Expand Down
40 changes: 40 additions & 0 deletions test/browser/lifecycles/componentWillMount.test.js
@@ -1,4 +1,5 @@
import { createElement, render, Component } from 'preact';
import { setupRerender } from 'preact/test-utils';
import { setupScratch, teardown } from '../../_util/helpers';

/** @jsx createElement */
Expand All @@ -7,8 +8,12 @@ describe('Lifecycle methods', () => {
/** @type {HTMLDivElement} */
let scratch;

/** @type {() => void} */
let rerender;

beforeEach(() => {
scratch = setupScratch();
rerender = setupRerender();
});

afterEach(() => {
Expand Down Expand Up @@ -39,5 +44,40 @@ describe('Lifecycle methods', () => {

expect(componentState).to.deep.equal({ value: 1 });
});

it('should invoke setState callbacks when setState is called in componentWillMount', () => {
let componentState;
let callback = sinon.spy();

class Foo extends Component {
constructor(props) {
super(props);
this.state = {
value: 0
};
}
componentWillMount() {
this.setState({ value: 1 }, callback);
this.setState({ value: 2 }, () => {
callback();
this.setState({ value: 3 }, callback);
});
}
render() {
componentState = this.state;
return <div />;
}
}

render(<Foo />, scratch);

expect(componentState).to.deep.equal({ value: 2 });
expect(callback).to.have.been.calledTwice;

rerender();

expect(componentState).to.deep.equal({ value: 3 });
expect(callback).to.have.been.calledThrice;
});
});
});

0 comments on commit d4089df

Please sign in to comment.