Skip to content

Commit

Permalink
Fix preact/debug throwing on string children
Browse files Browse the repository at this point in the history
  • Loading branch information
marvinhagemeister committed Oct 23, 2022
1 parent 32acce9 commit 8b944b2
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/brown-boats-nail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'preact-render-to-string': patch
---

Fix `preact/debug` incorrectly throwing errors on text children
23 changes: 22 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,23 @@ function renderClassComponent(vnode, context) {
return c.render(c.props, c.state, c.context);
}

/**
* @param {any} vnode
* @returns {VNode}
*/
function normalizeVNode(vnode) {
if (vnode == null || typeof vnode == 'boolean') {
return null;
} else if (
typeof vnode == 'string' ||
typeof vnode == 'number' ||
typeof vnode == 'bigint'
) {
return h(null, null, vnode);
}
return vnode;
}

/**
* @param {string} name
* @param {boolean} isSvgMode
Expand Down Expand Up @@ -237,6 +254,8 @@ function _renderToString(vnode, context, isSvgMode, selectValue, parent) {
rendered =
rendered +
_renderToString(vnode[i], context, isSvgMode, selectValue, parent);

vnode[i] = normalizeVNode(vnode[i]);
}
return rendered;
}
Expand Down Expand Up @@ -372,6 +391,8 @@ function _renderToString(vnode, context, isSvgMode, selectValue, parent) {
vnode[CHILDREN] = children;
for (let i = 0; i < children.length; i++) {
let child = children[i];
children[i] = normalizeVNode(child);

if (child != null && child !== false) {
let childSvgMode =
type === 'svg' || (type !== 'foreignObject' && isSvgMode);
Expand All @@ -391,7 +412,7 @@ function _renderToString(vnode, context, isSvgMode, selectValue, parent) {
}
}
} else if (children != null && children !== false && children !== true) {
vnode[CHILDREN] = [children];
vnode[CHILDREN] = [normalizeVNode(children)];
let childSvgMode =
type === 'svg' || (type !== 'foreignObject' && isSvgMode);
let ret = _renderToString(
Expand Down
26 changes: 26 additions & 0 deletions test/debug.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'preact/debug';
import { render } from '../src';
import { h } from 'preact';
import { expect } from 'chai';

describe('debug', () => {
it('should not throw "Objects are not valid as a child" error', () => {
expect(() => render(<p>{'foo'}</p>)).not.to.throw();
expect(() => render(<p>{2}</p>)).not.to.throw();
expect(() => render(<p>{true}</p>)).not.to.throw();
expect(() => render(<p>{false}</p>)).not.to.throw();
expect(() => render(<p>{null}</p>)).not.to.throw();
expect(() => render(<p>{undefined}</p>)).not.to.throw();
});

it('should not throw "Objects are not valid as a child" error #2', () => {
function Str() {
return ['foo'];
}
expect(() => render(<Str />)).not.to.throw();
});

it('should not throw "Objects are not valid as a child" error #3', () => {
expect(() => render(<p>{'foo'}bar</p>)).not.to.throw();
});
});

0 comments on commit 8b944b2

Please sign in to comment.