Skip to content

Commit 8b944b2

Browse files
Fix preact/debug throwing on string children
1 parent 32acce9 commit 8b944b2

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
lines changed

.changeset/brown-boats-nail.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'preact-render-to-string': patch
3+
---
4+
5+
Fix `preact/debug` incorrectly throwing errors on text children

src/index.js

+22-1
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,23 @@ function renderClassComponent(vnode, context) {
165165
return c.render(c.props, c.state, c.context);
166166
}
167167

168+
/**
169+
* @param {any} vnode
170+
* @returns {VNode}
171+
*/
172+
function normalizeVNode(vnode) {
173+
if (vnode == null || typeof vnode == 'boolean') {
174+
return null;
175+
} else if (
176+
typeof vnode == 'string' ||
177+
typeof vnode == 'number' ||
178+
typeof vnode == 'bigint'
179+
) {
180+
return h(null, null, vnode);
181+
}
182+
return vnode;
183+
}
184+
168185
/**
169186
* @param {string} name
170187
* @param {boolean} isSvgMode
@@ -237,6 +254,8 @@ function _renderToString(vnode, context, isSvgMode, selectValue, parent) {
237254
rendered =
238255
rendered +
239256
_renderToString(vnode[i], context, isSvgMode, selectValue, parent);
257+
258+
vnode[i] = normalizeVNode(vnode[i]);
240259
}
241260
return rendered;
242261
}
@@ -372,6 +391,8 @@ function _renderToString(vnode, context, isSvgMode, selectValue, parent) {
372391
vnode[CHILDREN] = children;
373392
for (let i = 0; i < children.length; i++) {
374393
let child = children[i];
394+
children[i] = normalizeVNode(child);
395+
375396
if (child != null && child !== false) {
376397
let childSvgMode =
377398
type === 'svg' || (type !== 'foreignObject' && isSvgMode);
@@ -391,7 +412,7 @@ function _renderToString(vnode, context, isSvgMode, selectValue, parent) {
391412
}
392413
}
393414
} else if (children != null && children !== false && children !== true) {
394-
vnode[CHILDREN] = [children];
415+
vnode[CHILDREN] = [normalizeVNode(children)];
395416
let childSvgMode =
396417
type === 'svg' || (type !== 'foreignObject' && isSvgMode);
397418
let ret = _renderToString(

test/debug.test.js

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import 'preact/debug';
2+
import { render } from '../src';
3+
import { h } from 'preact';
4+
import { expect } from 'chai';
5+
6+
describe('debug', () => {
7+
it('should not throw "Objects are not valid as a child" error', () => {
8+
expect(() => render(<p>{'foo'}</p>)).not.to.throw();
9+
expect(() => render(<p>{2}</p>)).not.to.throw();
10+
expect(() => render(<p>{true}</p>)).not.to.throw();
11+
expect(() => render(<p>{false}</p>)).not.to.throw();
12+
expect(() => render(<p>{null}</p>)).not.to.throw();
13+
expect(() => render(<p>{undefined}</p>)).not.to.throw();
14+
});
15+
16+
it('should not throw "Objects are not valid as a child" error #2', () => {
17+
function Str() {
18+
return ['foo'];
19+
}
20+
expect(() => render(<Str />)).not.to.throw();
21+
});
22+
23+
it('should not throw "Objects are not valid as a child" error #3', () => {
24+
expect(() => render(<p>{'foo'}bar</p>)).not.to.throw();
25+
});
26+
});

0 commit comments

Comments
 (0)