Skip to content

Commit ee4ad7d

Browse files
w4zZz4pmarvinhagemeister
authored andcommitted
Fix missing context with contextType for class components (#122)
1 parent 4234f34 commit ee4ad7d

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

src/index.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,18 @@ function renderToString(vnode, context, opts, inner, isSvgMode, selectValue) {
9292
}
9393
else {
9494
// class-based components
95+
let cxType = nodeName.contextType;
96+
let provider = cxType && context[cxType.__c];
97+
let cctx = cxType != null ? (provider ? provider.props.value : cxType._defaultValue) : context;
98+
9599
// c = new nodeName(props, context);
96-
c = vnode.__c = new nodeName(props, context);
100+
c = vnode.__c = new nodeName(props, cctx);
97101
c.__v = vnode;
98102
// turn off stateful re-rendering:
99103
c._dirty = c.__d = true;
100104
c.props = props;
101105
if (c.state==null) c.state = {};
102-
c.context = context;
106+
c.context = cctx;
103107
if (nodeName.getDerivedStateFromProps) c.state = assign(assign({}, c.state), nodeName.getDerivedStateFromProps(c.props, c.state));
104108
else if (c.componentWillMount) c.componentWillMount();
105109
rendered = c.render(c.props, c.state, c.context);

test/context.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import render from '../src/jsx';
2-
import { h, createContext } from 'preact';
2+
import { h, createContext, Component } from 'preact';
33
import chai, { expect } from 'chai';
44
import sinonChai from 'sinon-chai';
55
chai.use(sinonChai);
@@ -12,6 +12,32 @@ function dedent([str]) {
1212
describe('context', () => {
1313
let renderJsx = (jsx, opts) => render(jsx, null, opts).replace(/ {2}/g, '\t');
1414

15+
it('should support class component as consumer', () => {
16+
const Ctx = createContext();
17+
18+
class ClassConsumer extends Component {
19+
render() {
20+
const value = this.context;
21+
return (
22+
<section>
23+
value is: {value}
24+
</section>
25+
);
26+
}
27+
}
28+
ClassConsumer.contextType = Ctx;
29+
30+
let rendered = renderJsx(
31+
<Ctx.Provider value="correct">
32+
<ClassConsumer />
33+
</Ctx.Provider>
34+
);
35+
36+
expect(rendered).to.equal(dedent`
37+
<section>value is: correct</section>
38+
`);
39+
});
40+
1541
it('should support createContext', () => {
1642
const { Provider, Consumer } = createContext();
1743
let rendered = renderJsx(

0 commit comments

Comments
 (0)