Skip to content

Commit 481b4f3

Browse files
authored
fix: Support dangerouslySetInnerHTML={undefined} with renderToStringAsync (#381)
1 parent c8e54a1 commit 481b4f3

File tree

4 files changed

+71
-11
lines changed

4 files changed

+71
-11
lines changed

.changeset/chilly-ladybugs-think.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'preact-render-to-string': patch
3+
---
4+
5+
Support `dangerouslySetInnerHTML={undefined}` with `renderToStringAsync`

src/index.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,9 @@ export async function renderToStringAsync(vnode, context) {
125125

126126
// Resolving nested Promises with a maximum depth of 25
127127
while (
128-
resolved.some((element) => typeof element.then === 'function') &&
128+
resolved.some(
129+
(element) => element && typeof element.then === 'function'
130+
) &&
129131
count++ < 25
130132
) {
131133
resolved = (await Promise.all(resolved)).flat();

test/compat/async.test.jsx

+43
Original file line numberDiff line numberDiff line change
@@ -226,4 +226,47 @@ describe('Async renderToString', () => {
226226

227227
expect(rendered).to.equal(`<div>2</div>`);
228228
});
229+
230+
describe('dangerouslySetInnerHTML', () => {
231+
it('should support dangerouslySetInnerHTML', async () => {
232+
// some invalid HTML to make sure we're being flakey:
233+
let html = '<a href="foo">asdf</a> some text <ul><li>foo<li>bar</ul>';
234+
let rendered = await renderToStringAsync(
235+
<div id="f" dangerouslySetInnerHTML={{ __html: html }} />
236+
);
237+
expect(rendered).to.equal(`<div id="f">${html}</div>`);
238+
});
239+
240+
it('should accept undefined dangerouslySetInnerHTML', async () => {
241+
const Test = () => (
242+
<Fragment>
243+
<div>hi</div>
244+
<div dangerouslySetInnerHTML={undefined} />
245+
</Fragment>
246+
);
247+
248+
const rendered = await renderToStringAsync(<Test />);
249+
expect(rendered).to.equal('<div>hi</div><div></div>');
250+
});
251+
252+
it('should accept null __html', async () => {
253+
const Test = () => (
254+
<Fragment>
255+
<div>hi</div>
256+
<div dangerouslySetInnerHTML={{ __html: null }} />
257+
</Fragment>
258+
);
259+
const rendered = await renderToStringAsync(<Test />);
260+
expect(rendered).to.equal('<div>hi</div><div></div>');
261+
});
262+
263+
it('should override children', async () => {
264+
let rendered = await renderToStringAsync(
265+
<div dangerouslySetInnerHTML={{ __html: 'foo' }}>
266+
<b>bar</b>
267+
</div>
268+
);
269+
expect(rendered).to.equal('<div>foo</div>');
270+
});
271+
});
229272
});

test/render.test.jsx

+20-10
Original file line numberDiff line numberDiff line change
@@ -387,16 +387,6 @@ describe('render', () => {
387387
);
388388
});
389389

390-
it('should accept nullish __html', () => {
391-
const Test = (props) => (
392-
<Fragment>
393-
<div>hi</div>
394-
<div dangerouslySetInnerHTML={{ __html: null }} />
395-
</Fragment>
396-
);
397-
expect(render(<Test />)).to.equal('<div>hi</div><div></div>');
398-
});
399-
400390
it('should apply defaultProps', () => {
401391
const Test = (props) => <div {...props} />;
402392
Test.defaultProps = {
@@ -835,6 +825,26 @@ describe('render', () => {
835825
expect(rendered).to.equal(`<div id="f">${html}</div>`);
836826
});
837827

828+
it('should accept undefined dangerouslySetInnerHTML', () => {
829+
const Test = () => (
830+
<Fragment>
831+
<div>hi</div>
832+
<div dangerouslySetInnerHTML={undefined} />
833+
</Fragment>
834+
);
835+
expect(render(<Test />)).to.equal('<div>hi</div><div></div>');
836+
});
837+
838+
it('should accept null __html', () => {
839+
const Test = () => (
840+
<Fragment>
841+
<div>hi</div>
842+
<div dangerouslySetInnerHTML={{ __html: null }} />
843+
</Fragment>
844+
);
845+
expect(render(<Test />)).to.equal('<div>hi</div><div></div>');
846+
});
847+
838848
it('should override children', () => {
839849
let rendered = render(
840850
<div dangerouslySetInnerHTML={{ __html: 'foo' }}>

0 commit comments

Comments
 (0)