Skip to content

Commit 0b853e9

Browse files
committed
Fix and test for disabling stateful re-rendering during string rendering. Fixes preactjs/preact#524
1 parent 1a04dc0 commit 0b853e9

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ export default function renderToString(vnode, context, opts, inner, isSvgMode) {
8484
else {
8585
// class-based components
8686
let c = new nodeName(props, context);
87+
// turn off stateful re-rendering:
88+
c._disable = c.__x = true;
8789
c.props = props;
8890
c.context = context;
8991
if (c.componentWillMount) c.componentWillMount();

test/render.js

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { render, shallowRender } from '../src';
22
import { h, Component } from 'preact';
33
import chai, { expect } from 'chai';
4-
import { spy, match } from 'sinon';
4+
import { spy, stub, match } from 'sinon';
55
import sinonChai from 'sinon-chai';
66
chai.use(sinonChai);
77

@@ -467,4 +467,43 @@ describe('render', () => {
467467
expect(renderXml(<div foo={false} bar={0} />)).to.equal(`<div bar="0" />`);
468468
});
469469
});
470+
471+
describe('state locking', () => {
472+
it('should set _disable and __x to true', () => {
473+
let inst;
474+
class Foo extends Component {
475+
constructor(props, context) {
476+
super(props, context);
477+
inst = this;
478+
}
479+
render() {
480+
return <div />;
481+
}
482+
}
483+
484+
expect(render(<Foo />)).to.equal('<div></div>');
485+
486+
expect(inst).to.have.property('_disable', true);
487+
expect(inst).to.have.property('__x', true);
488+
});
489+
490+
it('should prevent re-rendering', () => {
491+
const Bar = stub().returns(<div />);
492+
493+
let count = 0;
494+
495+
class Foo extends Component {
496+
componentWillMount() {
497+
this.forceUpdate();
498+
}
499+
render() {
500+
return <Bar count={++count} />;
501+
}
502+
}
503+
504+
expect(render(<Foo />)).to.equal('<div></div>');
505+
506+
expect(Bar).to.have.been.calledOnce.and.calledWithMatch({ count: 1 });
507+
});
508+
});
470509
});

0 commit comments

Comments
 (0)