Skip to content

Commit e8c1fd8

Browse files
Fix wrong value for useContext
1 parent 72dd2b3 commit e8c1fd8

File tree

2 files changed

+45
-12
lines changed

2 files changed

+45
-12
lines changed

src/index.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,28 +60,29 @@ function renderToString(vnode, context, opts, inner, isSvgMode) {
6060
nodeName = getComponentName(nodeName);
6161
}
6262
else {
63-
vnode.__c = { __v: vnode };
64-
if (options.render) options.render(vnode);
6563
let rendered;
64+
65+
let c = vnode.__c = { __v: vnode, context, props: vnode.props };
66+
if (options.render) options.render(vnode);
6667

6768
if (!nodeName.prototype || typeof nodeName.prototype.render!=='function') {
6869
// stateless functional components
69-
rendered = nodeName.apply(vnode.__c, props, context);
70+
rendered = nodeName.call(vnode.__c, props, context);
7071
}
7172
else {
7273
// class-based components
73-
let c = new nodeName(props, context);
74+
c = new nodeName(props, context);
7475
// turn off stateful re-rendering:
7576
c._dirty = c.__d = true;
7677
c.props = props;
7778
c.context = context;
7879
if (nodeName.getDerivedStateFromProps) c.state = assign(assign({}, c.state), nodeName.getDerivedStateFromProps(c.props, c.state));
7980
else if (c.componentWillMount) c.componentWillMount();
8081
rendered = c.render(c.props, c.state, c.context);
81-
82-
if (c.getChildContext) {
83-
context = assign(assign({}, context), c.getChildContext());
84-
}
82+
}
83+
84+
if (c.getChildContext) {
85+
context = assign(assign({}, context), c.getChildContext());
8586
}
8687

8788
return renderToString(rendered, context, opts, opts.shallowHighOrder!==false);

test/render.js

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { render, shallowRender } from '../src';
22
import { h, Component, createContext } from 'preact';
3-
import { useState, useContext } from 'preact/hooks';
3+
import { useState, useContext, useEffect } from 'preact/hooks';
44
import chai, { expect } from 'chai';
55
import { spy, stub, match } from 'sinon';
66
import sinonChai from 'sinon-chai';
@@ -621,20 +621,52 @@ describe('render', () => {
621621
}).to.not.throw();
622622
});
623623

624-
it('should work with useContext', () => {
624+
it('should work with useContext and default value', () => {
625+
let Ctx = createContext('foo');
626+
function Foo() {
627+
let v = useContext(Ctx);
628+
return <div>{v}</div>;
629+
}
630+
631+
let res = render(<Foo />);
632+
633+
expect(res).to.equal('<div>foo</div>');
634+
});
635+
636+
it('should work with useContext + custom value', () => {
625637
let Ctx = createContext('foo');
626638
function Foo() {
627639
let v = useContext(Ctx);
628640
return <div>{v}</div>;
629641
}
630642

631643
let res = render(
632-
<Ctx.Provider value="foo">
644+
<Ctx.Provider value="bar">
633645
<Foo />
634646
</Ctx.Provider>
635647
);
636648

637-
expect(res).to.equal('<div>foo</div>');
649+
expect(res).to.equal('<div>bar</div>');
650+
});
651+
652+
it('should work with useState', () => {
653+
function Foo() {
654+
let [v] = useState(0);
655+
return <div>{v}</div>;
656+
}
657+
658+
expect(render(<Foo />)).to.equal('<div>0</div>');
659+
});
660+
661+
it('should not trigger useEffect callbacks', () => {
662+
let called = false;
663+
function Foo() {
664+
useEffect(() => called = true);
665+
return <div />;
666+
}
667+
668+
render(<Foo />);
669+
expect(called).to.equal(false);
638670
});
639671
});
640672
});

0 commit comments

Comments
 (0)