mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Fix duplicate declaration from MergeConsecutiveScopes
This is a distilled version of the duplicate declaration @mofeiZ and I saw when trying to sync latest Forget internally, plus a fix to avoid the duplicate instruction.
This commit is contained in:
+10
-1
@@ -108,6 +108,9 @@ class Transform extends ReactiveFunctionTransform<void> {
|
||||
// The updated set of instructions for the block. Stays null until
|
||||
// we make changes (ie merge scopes)
|
||||
let nextInstructions: ReactiveBlock | null = null;
|
||||
// The maximum index within the original instructions that we have reached.
|
||||
// Used to avoid emitting duplicate instructions
|
||||
let maxIndex: number = 0;
|
||||
|
||||
// Called when we find some instruction that cannot be merged into a
|
||||
// preceding scope, or we otherwise need to reset and not consider
|
||||
@@ -121,8 +124,14 @@ class Transform extends ReactiveFunctionTransform<void> {
|
||||
if (currentScope !== null) {
|
||||
nextInstructions.push(...block.slice(currentScope.to, index));
|
||||
}
|
||||
if (index < block.length) {
|
||||
// We can sometimes call resetCurrentScope twice for the same index,
|
||||
// such as when an instruction resets and then a subsequent scope also resets.
|
||||
// This is the only case in which we push instructions w/o gating on
|
||||
// `currentScope != null`, so we avoid duplicates by checking the max index
|
||||
// already emitted.
|
||||
if (index < block.length && index > maxIndex) {
|
||||
nextInstructions.push(block[index]!);
|
||||
maxIndex = index;
|
||||
}
|
||||
}
|
||||
currentScope = null;
|
||||
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
// @enableMergeConsecutiveScopes
|
||||
function Component(id) {
|
||||
const bar = (() => {})();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Bar title={bar} />
|
||||
<Bar title={id ? true : false} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [null],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import { unstable_useMemoCache as useMemoCache } from "react"; // @enableMergeConsecutiveScopes
|
||||
function Component(id) {
|
||||
const $ = useMemoCache(4);
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = (() => {})();
|
||||
$[0] = t0;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
}
|
||||
const bar = t0;
|
||||
let t1;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = <Bar title={bar} />;
|
||||
$[1] = t1;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
}
|
||||
const t2 = id ? true : false;
|
||||
const c_2 = $[2] !== t2;
|
||||
let t3;
|
||||
if (c_2) {
|
||||
t3 = (
|
||||
<>
|
||||
{t1}
|
||||
<Bar title={t2} />
|
||||
</>
|
||||
);
|
||||
$[2] = t2;
|
||||
$[3] = t3;
|
||||
} else {
|
||||
t3 = $[3];
|
||||
}
|
||||
return t3;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [null],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// @enableMergeConsecutiveScopes
|
||||
function Component(id) {
|
||||
const bar = (() => {})();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Bar title={bar} />
|
||||
<Bar title={id ? true : false} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [null],
|
||||
};
|
||||
Reference in New Issue
Block a user