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

[babel-plugin-react-jsx] Avoid duplicate "children" key in props object #17094

Merged
merged 2 commits into from
Oct 15, 2019
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
Original file line number Diff line number Diff line change
Expand Up @@ -480,4 +480,10 @@ describe('transform react to jsx', () => {
transform(`<Component y={2} {...x} />`, {useBuiltIns: false})
).toMatchSnapshot();
});

it('should not contain duplicate children key in props object', () => {
expect(
transform(`<Component children={1}>2</Component>`)
).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,14 @@ var e = React.jsx(F, {
});
`;

exports[`transform react to jsx should not contain duplicate children key in props object 1`] = `
React.jsx(Component, Object.assign({
children: 1
}, {
children: "2"
}));
`;

exports[`transform react to jsx should not strip nbsp even couple with other whitespace 1`] = `
React.jsx("div", {
children: "\\xA0 "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,11 +268,20 @@ You can turn on the 'throwIfNamespace' flag to bypass this warning.`,
);
}

function isChildrenProp(prop) {
return (
t.isJSXAttribute(prop) &&
t.isJSXIdentifier(prop.name) &&
prop.name.name === 'children'
);
}

// Builds props for React.jsx. This function adds children into the props
// and ensures that props is always an object
function buildJSXOpeningElementAttributes(attribs, file, children) {
let _props = [];
const objs = [];
const hasChildren = children && children.length > 0;

const useBuiltIns = file.opts.useBuiltIns || false;
if (typeof useBuiltIns !== 'boolean') {
Expand All @@ -287,14 +296,22 @@ You can turn on the 'throwIfNamespace' flag to bypass this warning.`,
if (t.isJSXSpreadAttribute(prop)) {
_props = pushProps(_props, objs);
objs.push(prop.argument);
} else if (hasChildren && isChildrenProp(prop)) {
// In order to avoid having duplicate "children" keys, we avoid
// pushing the "children" prop if we have actual children. Instead
// we put the children into a separate object and then rely on
// the Object.assign logic below to ensure the correct object is
// formed.
_props = pushProps(_props, objs);
objs.push(t.objectExpression([convertAttribute(prop)]));
} else {
_props.push(convertAttribute(prop));
}
}

// In React.JSX, children is no longer a separate argument, but passed in
// through the argument object
if (children && children.length > 0) {
if (hasChildren) {
if (children.length === 1) {
_props.push(t.objectProperty(t.identifier('children'), children[0]));
} else {
Expand Down