Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support passing children as props to a React component #5886

Merged
merged 1 commit into from
Jan 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fresh-eels-speak.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/react': patch
---

Support passing `children` as props to a React component
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import React from 'react';

export default function ({ children }) {
return <div className="with-children">{children}</div>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {Research2} from '../components/Research.jsx';
import Pure from '../components/Pure.jsx';
import TypeScriptComponent from '../components/TypeScriptComponent';
import CloneElement from '../components/CloneElement';
import WithChildren from '../components/WithChildren';

const someProps = {
text: 'Hello world!',
Expand All @@ -31,5 +32,7 @@ const someProps = {
<TypeScriptComponent client:load />
<Pure />
<CloneElement />
<WithChildren client:load>test</WithChildren>
<WithChildren client:load children="test" />
</body>
</html>
9 changes: 7 additions & 2 deletions packages/astro/test/react-component.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,16 @@ describe('React Components', () => {
expect($('#pure')).to.have.lengthOf(1);

// test 8: Check number of islands
expect($('astro-island[uid]')).to.have.lengthOf(5);
expect($('astro-island[uid]')).to.have.lengthOf(7);

// test 9: Check island deduplication
const uniqueRootUIDs = new Set($('astro-island').map((i, el) => $(el).attr('uid')));
expect(uniqueRootUIDs.size).to.equal(4);
expect(uniqueRootUIDs.size).to.equal(6);

// test 10: Should properly render children passed as props
const islandsWithChildren = $('.with-children');
expect(islandsWithChildren).to.have.lengthOf(2);
expect($(islandsWithChildren[0]).html()).to.equal($(islandsWithChildren[1]).html());
});

it('Can load Vue', async () => {
Expand Down
5 changes: 4 additions & 1 deletion packages/integrations/react/server-v17.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,11 @@ function renderToStaticMarkup(Component, props, { default: children, ...slotted
const newProps = {
...props,
...slots,
children: children != null ? React.createElement(StaticHtml, { value: children }) : undefined,
};
const newChildren = children ?? props.children;
if (newChildren != null) {
newProps.children = React.createElement(StaticHtml, { value: newChildren });
}
const vnode = React.createElement(Component, newProps);
let html;
if (metadata && metadata.hydrate) {
Expand Down
5 changes: 3 additions & 2 deletions packages/integrations/react/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@ async function renderToStaticMarkup(Component, props, { default: children, ...sl
...props,
...slots,
};
if (children != null) {
newProps.children = React.createElement(StaticHtml, { value: children });
const newChildren = children ?? props.children;
if (newChildren != null) {
newProps.children = React.createElement(StaticHtml, { value: newChildren });
}
const vnode = React.createElement(Component, newProps);
let html;
Expand Down