0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-01-06 22:10:10 -05:00

fix(react): make children undefined with experimentalReactChildren (#9141)

* add test script

* make children `undefined` with self-closing tags

* add changeset

* refactor: simplify
This commit is contained in:
Arsh 2023-11-21 17:19:43 +00:00 committed by GitHub
parent d9e72cea39
commit af43fb5172
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 12 deletions

View file

@ -0,0 +1,5 @@
---
'@astrojs/react': patch
---
Fixes an issue where slotting self-closing elements (img, br, hr) into react components with `experimentalReactChildren` enabled led to an error.

View file

@ -42,7 +42,8 @@
"scripts": {
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
"dev": "astro-scripts dev \"src/**/*.ts\""
"dev": "astro-scripts dev \"src/**/*.ts\"",
"test": "mocha --exit --timeout 20000"
},
"dependencies": {
"@vitejs/plugin-react": "^4.0.4",
@ -57,7 +58,8 @@
"cheerio": "1.0.0-rc.12",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"vite": "^4.4.9"
"vite": "^4.4.9",
"mocha": "^10.2.0"
},
"peerDependencies": {
"@types/react": "^17.0.50 || ^18.0.21",

View file

@ -0,0 +1,15 @@
import { expect } from 'chai';
import convert from "../vnode-children.js";
describe('experimental react children', () => {
it('has undefined as children for direct children', () => {
const [ imgVNode ] = convert('<img src="abc"></img>');
expect(imgVNode.props).to.deep.include({ children: undefined });
})
it('has undefined as children for nested children', () => {
const [ divVNode ] = convert('<div><img src="xyz"></img></div>');
const [ imgVNode ] = divVNode.props.children;
expect(imgVNode.props).to.deep.include({ children: undefined });
})
})

View file

@ -8,17 +8,10 @@ export default function convert(children) {
let key = 0;
function createReactElementFromNode(node) {
const childVnodes = Array.isArray(node.children)
const childVnodes = Array.isArray(node.children) && node.children.length
? node.children
.map((child) => {
if (child.type === ELEMENT_NODE) {
return createReactElementFromNode(child);
} else if (child.type === TEXT_NODE) {
// 0-length text gets omitted in JSX
return child.value.trim() ? child.value : undefined;
}
})
.filter((n) => !!n)
.map((child) => createReactElementFromNode(child))
.filter(Boolean)
: undefined;
if (node.type === DOCUMENT_NODE) {
@ -26,6 +19,9 @@ export default function convert(children) {
} else if (node.type === ELEMENT_NODE) {
const { class: className, ...props } = node.attributes;
return createElement(node.name, { ...props, className, key: `${id}-${key++}` }, childVnodes);
} else if (node.type === TEXT_NODE) {
// 0-length text gets omitted in JSX
return node.value.trim() ? node.value : undefined;
}
}

View file

@ -4473,6 +4473,9 @@ importers:
cheerio:
specifier: 1.0.0-rc.12
version: 1.0.0-rc.12
mocha:
specifier: ^10.2.0
version: 10.2.0
react:
specifier: ^18.1.0
version: 18.2.0