mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[compiler] Fix dropped ref with spread props in InlineJsxTransform (#31726)
When supporting ref as prop in https://github.com/facebook/react/pull/31558, I missed fixing the optimization to pass a spread-props-only props object in without an additional object copy. In the case that we have only a ref along with a spread, we cannot return only the spread object. This results in dropping the ref. In this example ```javascript <Foo ref={ref} {...props} /> ``` The bugged output is: ```javascript { // ... props: props } ``` With this change we now get the correct output: ```javascript { // ... props: {ref: ref, ...props} } ```
This commit is contained in:
+3
-5
@@ -546,16 +546,14 @@ function createPropsProperties(
|
||||
let refProperty: ObjectProperty | undefined;
|
||||
let keyProperty: ObjectProperty | undefined;
|
||||
const props: Array<ObjectProperty | SpreadPattern> = [];
|
||||
const jsxAttributesWithoutKeyAndRef = propAttributes.filter(
|
||||
p => p.kind === 'JsxAttribute' && p.name !== 'key' && p.name !== 'ref',
|
||||
const jsxAttributesWithoutKey = propAttributes.filter(
|
||||
p => p.kind === 'JsxAttribute' && p.name !== 'key',
|
||||
);
|
||||
const jsxSpreadAttributes = propAttributes.filter(
|
||||
p => p.kind === 'JsxSpreadAttribute',
|
||||
);
|
||||
const spreadPropsOnly =
|
||||
jsxAttributesWithoutKeyAndRef.length === 0 &&
|
||||
jsxSpreadAttributes.length === 1;
|
||||
|
||||
jsxAttributesWithoutKey.length === 0 && jsxSpreadAttributes.length === 1;
|
||||
propAttributes.forEach(prop => {
|
||||
switch (prop.kind) {
|
||||
case 'JsxAttribute': {
|
||||
|
||||
+39
@@ -60,6 +60,10 @@ function ConditionalJsx({shouldWrap}) {
|
||||
return content;
|
||||
}
|
||||
|
||||
function ComponentWithSpreadPropsAndRef({ref, ...other}) {
|
||||
return <Foo ref={ref} {...other} />;
|
||||
}
|
||||
|
||||
// TODO: Support value blocks
|
||||
function TernaryJsx({cond}) {
|
||||
return cond ? <div /> : null;
|
||||
@@ -409,6 +413,41 @@ function ConditionalJsx(t0) {
|
||||
return content;
|
||||
}
|
||||
|
||||
function ComponentWithSpreadPropsAndRef(t0) {
|
||||
const $ = _c2(6);
|
||||
let other;
|
||||
let ref;
|
||||
if ($[0] !== t0) {
|
||||
({ ref, ...other } = t0);
|
||||
$[0] = t0;
|
||||
$[1] = other;
|
||||
$[2] = ref;
|
||||
} else {
|
||||
other = $[1];
|
||||
ref = $[2];
|
||||
}
|
||||
let t1;
|
||||
if ($[3] !== other || $[4] !== ref) {
|
||||
if (DEV) {
|
||||
t1 = <Foo ref={ref} {...other} />;
|
||||
} else {
|
||||
t1 = {
|
||||
$$typeof: Symbol.for("react.transitional.element"),
|
||||
type: Foo,
|
||||
ref: ref,
|
||||
key: null,
|
||||
props: { ref: ref, ...other },
|
||||
};
|
||||
}
|
||||
$[3] = other;
|
||||
$[4] = ref;
|
||||
$[5] = t1;
|
||||
} else {
|
||||
t1 = $[5];
|
||||
}
|
||||
return t1;
|
||||
}
|
||||
|
||||
// TODO: Support value blocks
|
||||
function TernaryJsx(t0) {
|
||||
const $ = _c2(2);
|
||||
|
||||
+4
@@ -56,6 +56,10 @@ function ConditionalJsx({shouldWrap}) {
|
||||
return content;
|
||||
}
|
||||
|
||||
function ComponentWithSpreadPropsAndRef({ref, ...other}) {
|
||||
return <Foo ref={ref} {...other} />;
|
||||
}
|
||||
|
||||
// TODO: Support value blocks
|
||||
function TernaryJsx({cond}) {
|
||||
return cond ? <div /> : null;
|
||||
|
||||
Reference in New Issue
Block a user