Skip to content

Commit

Permalink
Merge pull request #592 from wyze/forceupdate-callback
Browse files Browse the repository at this point in the history
Add optional callback to forceUpdate method
  • Loading branch information
robertknight authored Apr 2, 2017
2 parents 2b9d81f + bb6da19 commit ac61ab9
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 2 deletions.
4 changes: 3 additions & 1 deletion src/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,11 @@ extend(Component.prototype, {


/** Immediately perform a synchronous re-render of the component.
* @param {function} callback A function to be called after component is re-rendered.
* @private
*/
forceUpdate() {
forceUpdate(callback) {
if (callback) (this._renderCallbacks = (this._renderCallbacks || [])).push(callback);
renderComponent(this, FORCE_RENDER);
},

Expand Down
2 changes: 1 addition & 1 deletion src/preact.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ declare namespace preact {
setState<K extends keyof StateType>(state:Pick<StateType, K>, callback?:() => void):void;
setState<K extends keyof StateType>(fn:(prevState:StateType, props:PropsType) => Pick<StateType, K>, callback?:() => void):void;

forceUpdate(): void;
forceUpdate(callback?:() => void): void;

abstract render(props?:PropsType & ComponentProps<this>, state?:StateType, context?:any):JSX.Element;
}
Expand Down
45 changes: 45 additions & 0 deletions test/browser/spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,49 @@ describe('Component spec', () => {
expect(WithDefaultProps.prototype.getDefaultProps).to.be.calledOnce;
});
});

describe('forceUpdate', () => {
it('should force a rerender', () => {
let forceUpdate;
class ForceUpdateComponent extends Component {
componentWillUpdate() {}
componentDidMount() {
forceUpdate = () => this.forceUpdate();
}
render() {
return <div />;
}
}
sinon.spy(ForceUpdateComponent.prototype, 'componentWillUpdate');
sinon.spy(ForceUpdateComponent.prototype, 'forceUpdate');
render(<ForceUpdateComponent />, scratch);
expect(ForceUpdateComponent.prototype.componentWillUpdate).not.to.have.been.called;

forceUpdate();

expect(ForceUpdateComponent.prototype.componentWillUpdate).to.have.been.called;
expect(ForceUpdateComponent.prototype.forceUpdate).to.have.been.called;
});

it('should add callback to renderCallbacks', () => {
let forceUpdate;
let callback = sinon.spy();
class ForceUpdateComponent extends Component {
componentDidMount() {
forceUpdate = () => this.forceUpdate(callback);
}
render() {
return <div />;
}
}
sinon.spy(ForceUpdateComponent.prototype, 'forceUpdate');
render(<ForceUpdateComponent />, scratch);

forceUpdate();

expect(ForceUpdateComponent.prototype.forceUpdate).to.have.been.called;
expect(ForceUpdateComponent.prototype.forceUpdate).to.have.been.calledWith(callback);
expect(callback).to.have.been.called;
});
});
});

0 comments on commit ac61ab9

Please sign in to comment.