Allow children to be passed as props in React

Closes #681
This commit is contained in:
Matthew Phillips 2021-07-13 17:04:11 -04:00
parent d07f3d4186
commit 0de469d273
4 changed files with 41 additions and 4 deletions

View file

@ -0,0 +1,7 @@
import React from 'react';
export default ({ id, children }) => {
return (
<div id={id}>{children}</div>
);
}

View file

@ -0,0 +1,12 @@
---
import Child from '../components/Child.jsx';
---
<html>
<head><title>Children tests</title></head>
<body>
<Child id="content"><span>content</span></Child>
<Child id="prop" children={<span>prop</span>} />
<Child id="prop-and-content" children={<span>prop</span>}><span>content</span></Child>
</body>
</html>

View file

@ -79,4 +79,14 @@ React('Get good error message when react import is forgotten', async () => {
assert.equal(result.error.message, 'React is not defined'); assert.equal(result.error.message, 'React is not defined');
}); });
React('Children passed as props', async () => {
const result = await runtime.load('/child-prop');
const html = result.contents;
const $ = doc(html);
assert.equal($('#content').html(), '<span>content</span>');
assert.equal($('#prop').html(), '<span>prop</span>');
assert.equal($('#prop-and-content').html(), '<span>content</span>');
});
React.run(); React.run();

View file

@ -4,7 +4,7 @@ import StaticHtml from './static-html.js';
const reactTypeof = Symbol.for('react.element'); const reactTypeof = Symbol.for('react.element');
function check(Component, props, children) { async function check(Component, props, children) {
if (typeof Component !== 'function') return false; if (typeof Component !== 'function') return false;
if (Component.prototype != null && typeof Component.prototype.render === 'function') { if (Component.prototype != null && typeof Component.prototype.render === 'function') {
@ -26,16 +26,24 @@ function check(Component, props, children) {
return h('div'); return h('div');
} }
renderToStaticMarkup(Tester, props, children, {}); await renderToStaticMarkup(Tester, props, children, {});
if (error) { if (error) {
throw error; throw error;
} }
return isReactComponent; return isReactComponent;
} }
function renderToStaticMarkup(Component, props, children, metadata) { async function renderToStaticMarkup(Component, props, children, metadata) {
const vnode = h(Component, { ...props, children: h(StaticHtml, { value: children }), innerHTML: children }); const childrenValue = children || (await props.children);
const vnode = h(Component, {
...props,
children: h(StaticHtml, {
value: childrenValue
}),
innerHTML: children
});
let html; let html;
if (metadata && metadata.hydrate) { if (metadata && metadata.hydrate) {
html = renderToString(vnode); html = renderToString(vnode);