Skip to content

Commit 8d35c25

Browse files
Support createContext of preact x (#88)
Support createContext of preact x
2 parents 66b35a1 + 0d2aca2 commit 8d35c25

File tree

2 files changed

+80
-1
lines changed

2 files changed

+80
-1
lines changed

src/index.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,14 @@ function renderToString(vnode, context, opts, inner, isSvgMode, selectValue) {
7676
if (options.render) options.render(vnode);
7777

7878
if (!nodeName.prototype || typeof nodeName.prototype.render!=='function') {
79+
// Necessary for createContext api. Setting this property will pass
80+
// the context value as `this.context` just for this component.
81+
let cxType = nodeName.contextType;
82+
let provider = cxType && context[cxType.__c];
83+
let cctx = cxType != null ? (provider ? provider.props.value : cxType._defaultValue) : context;
84+
7985
// stateless functional components
80-
rendered = nodeName.call(vnode.__c, props, context);
86+
rendered = nodeName.call(vnode.__c, props, cctx);
8187
}
8288
else {
8389
// class-based components

test/context.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import render from '../src/jsx';
2+
import { h, createContext } from 'preact';
3+
import chai, { expect } from 'chai';
4+
import sinonChai from 'sinon-chai';
5+
chai.use(sinonChai);
6+
7+
// tag to remove leading whitespace from tagged template literal
8+
function dedent([str]) {
9+
return str.split( '\n'+str.match(/^\n*(\s+)/)[1] ).join('\n').replace(/(^\n+|\n+\s*$)/g, '');
10+
}
11+
12+
describe('context', () => {
13+
let renderJsx = (jsx, opts) => render(jsx, null, opts).replace(/ {2}/g, '\t');
14+
15+
it('should support createContext', () => {
16+
const { Provider, Consumer } = createContext();
17+
let rendered = renderJsx(
18+
<Provider value="correct">
19+
<Consumer>
20+
{(value) => (
21+
<section>
22+
value is: {value}
23+
</section>
24+
)}
25+
</Consumer>
26+
</Provider>
27+
);
28+
29+
expect(rendered).to.equal(dedent`
30+
<section>value is: correct</section>
31+
`);
32+
});
33+
34+
it('should support nested Providers', () => {
35+
const { Provider, Consumer } = createContext();
36+
let rendered = renderJsx(
37+
<Provider value="wrong">
38+
<Provider value="correct">
39+
<Consumer>
40+
{(value) => (
41+
<section>
42+
value is: {value}
43+
</section>
44+
)}
45+
</Consumer>
46+
</Provider>
47+
</Provider>
48+
);
49+
50+
expect(rendered).to.equal(dedent`
51+
<section>value is: correct</section>
52+
`);
53+
});
54+
55+
it('should support falsy context value', () => {
56+
const { Provider, Consumer } = createContext();
57+
let rendered = renderJsx(
58+
<Provider value={null}>
59+
<Consumer>
60+
{(value) => (
61+
<section>
62+
value is: {value}
63+
</section>
64+
)}
65+
</Consumer>
66+
</Provider>
67+
);
68+
69+
expect(rendered).to.equal(dedent`
70+
<section>value is: </section>
71+
`);
72+
});
73+
});

0 commit comments

Comments
 (0)