From 0de469d273013c0cfcce6443d69a8dcdb4fb2181 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Tue, 13 Jul 2021 17:04:11 -0400 Subject: [PATCH] Allow children to be passed as props in React Closes #681 --- .../react-component/src/components/Child.jsx | 7 +++++++ .../react-component/src/pages/child-prop.astro | 12 ++++++++++++ packages/astro/test/react-component.test.js | 10 ++++++++++ packages/renderers/renderer-react/server.js | 16 ++++++++++++---- 4 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 packages/astro/test/fixtures/react-component/src/components/Child.jsx create mode 100644 packages/astro/test/fixtures/react-component/src/pages/child-prop.astro diff --git a/packages/astro/test/fixtures/react-component/src/components/Child.jsx b/packages/astro/test/fixtures/react-component/src/components/Child.jsx new file mode 100644 index 000000000..730f25a03 --- /dev/null +++ b/packages/astro/test/fixtures/react-component/src/components/Child.jsx @@ -0,0 +1,7 @@ +import React from 'react'; + +export default ({ id, children }) => { + return ( +
{children}
+ ); +} \ No newline at end of file diff --git a/packages/astro/test/fixtures/react-component/src/pages/child-prop.astro b/packages/astro/test/fixtures/react-component/src/pages/child-prop.astro new file mode 100644 index 000000000..8c3421835 --- /dev/null +++ b/packages/astro/test/fixtures/react-component/src/pages/child-prop.astro @@ -0,0 +1,12 @@ +--- +import Child from '../components/Child.jsx'; +--- + + +Children tests + + content + prop} /> + prop}>content + + \ No newline at end of file diff --git a/packages/astro/test/react-component.test.js b/packages/astro/test/react-component.test.js index ac80b3b6d..7a87fd3ca 100644 --- a/packages/astro/test/react-component.test.js +++ b/packages/astro/test/react-component.test.js @@ -79,4 +79,14 @@ React('Get good error message when react import is forgotten', async () => { 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(), 'content'); + assert.equal($('#prop').html(), 'prop'); + assert.equal($('#prop-and-content').html(), 'content'); +}); + React.run(); diff --git a/packages/renderers/renderer-react/server.js b/packages/renderers/renderer-react/server.js index 5eded5afa..7702457af 100644 --- a/packages/renderers/renderer-react/server.js +++ b/packages/renderers/renderer-react/server.js @@ -4,7 +4,7 @@ import StaticHtml from './static-html.js'; const reactTypeof = Symbol.for('react.element'); -function check(Component, props, children) { +async function check(Component, props, children) { if (typeof Component !== 'function') return false; if (Component.prototype != null && typeof Component.prototype.render === 'function') { @@ -26,16 +26,24 @@ function check(Component, props, children) { return h('div'); } - renderToStaticMarkup(Tester, props, children, {}); + await renderToStaticMarkup(Tester, props, children, {}); if (error) { throw error; } + return isReactComponent; } -function renderToStaticMarkup(Component, props, children, metadata) { - const vnode = h(Component, { ...props, children: h(StaticHtml, { value: children }), innerHTML: children }); +async function renderToStaticMarkup(Component, props, children, metadata) { + const childrenValue = children || (await props.children); + const vnode = h(Component, { + ...props, + children: h(StaticHtml, { + value: childrenValue + }), + innerHTML: children + }); let html; if (metadata && metadata.hydrate) { html = renderToString(vnode);