Skip to content

Commit

Permalink
Remove RefreshRuntime.findAffectedHostInstances
Browse files Browse the repository at this point in the history
  • Loading branch information
gaearon committed Jul 30, 2024
1 parent edfaa99 commit 96b62ef
Show file tree
Hide file tree
Showing 4 changed files with 0 additions and 292 deletions.
152 changes: 0 additions & 152 deletions packages/react-reconciler/src/ReactFiberHotReloading.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,6 @@ type RefreshHandler = any => Family | void;
export type SetRefreshHandler = (handler: RefreshHandler | null) => void;
export type ScheduleRefresh = (root: FiberRoot, update: RefreshUpdate) => void;
export type ScheduleRoot = (root: FiberRoot, element: ReactNodeList) => void;
export type FindHostInstancesForRefresh = (
root: FiberRoot,
families: Array<Family>,
) => Set<Instance>;

let resolveFamily: RefreshHandler | null = null;
let failedBoundaries: WeakSet<Fiber> | null = null;
Expand Down Expand Up @@ -343,151 +339,3 @@ function scheduleFibersWithFamiliesRecursively(
}
}
}

export const findHostInstancesForRefresh: FindHostInstancesForRefresh = (
root: FiberRoot,
families: Array<Family>,
): Set<Instance> => {
if (__DEV__) {
const hostInstances = new Set<Instance>();
const types = new Set(families.map(family => family.current));
findHostInstancesForMatchingFibersRecursively(
root.current,
types,
hostInstances,
);
return hostInstances;
} else {
throw new Error(
'Did not expect findHostInstancesForRefresh to be called in production.',
);
}
};

function findHostInstancesForMatchingFibersRecursively(
fiber: Fiber,
types: Set<any>,
hostInstances: Set<Instance>,
) {
if (__DEV__) {
const {child, sibling, tag, type} = fiber;

let candidateType = null;
switch (tag) {
case FunctionComponent:
case SimpleMemoComponent:
case ClassComponent:
candidateType = type;
break;
case ForwardRef:
candidateType = type.render;
break;
default:
break;
}

let didMatch = false;
if (candidateType !== null) {
if (types.has(candidateType)) {
didMatch = true;
}
}

if (didMatch) {
// We have a match. This only drills down to the closest host components.
// There's no need to search deeper because for the purpose of giving
// visual feedback, "flashing" outermost parent rectangles is sufficient.
findHostInstancesForFiberShallowly(fiber, hostInstances);
} else {
// If there's no match, maybe there will be one further down in the child tree.
if (child !== null) {
findHostInstancesForMatchingFibersRecursively(
child,
types,
hostInstances,
);
}
}

if (sibling !== null) {
findHostInstancesForMatchingFibersRecursively(
sibling,
types,
hostInstances,
);
}
}
}

function findHostInstancesForFiberShallowly(
fiber: Fiber,
hostInstances: Set<Instance>,
): void {
if (__DEV__) {
const foundHostInstances = findChildHostInstancesForFiberShallowly(
fiber,
hostInstances,
);
if (foundHostInstances) {
return;
}
// If we didn't find any host children, fallback to closest host parent.
let node = fiber;
while (true) {
switch (node.tag) {
case HostSingleton:
case HostComponent:
hostInstances.add(node.stateNode);
return;
case HostPortal:
hostInstances.add(node.stateNode.containerInfo);
return;
case HostRoot:
hostInstances.add(node.stateNode.containerInfo);
return;
}
if (node.return === null) {
throw new Error('Expected to reach root first.');
}
node = node.return;
}
}
}

function findChildHostInstancesForFiberShallowly(
fiber: Fiber,
hostInstances: Set<Instance>,
): boolean {
if (__DEV__) {
let node: Fiber = fiber;
let foundHostInstances = false;
while (true) {
if (
node.tag === HostComponent ||
node.tag === HostHoistable ||
(supportsSingletons ? node.tag === HostSingleton : false)
) {
// We got a match.
foundHostInstances = true;
hostInstances.add(node.stateNode);
// There may still be more, so keep searching.
} else if (node.child !== null) {
node.child.return = node;
node = node.child;
continue;
}
if (node === fiber) {
return foundHostInstances;
}
while (node.sibling === null) {
if (node.return === null || node.return === fiber) {
return foundHostInstances;
}
node = node.return;
}
node.sibling.return = node.return;
node = node.sibling;
}
}
return false;
}
2 changes: 0 additions & 2 deletions packages/react-reconciler/src/ReactFiberReconciler.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ import {
scheduleRefresh,
scheduleRoot,
setRefreshHandler,
findHostInstancesForRefresh,
} from './ReactFiberHotReloading';
import ReactVersion from 'shared/ReactVersion';
export {createPortal} from './ReactPortal';
Expand Down Expand Up @@ -865,7 +864,6 @@ export function injectIntoDevTools(): boolean {
internals.setErrorHandler = setErrorHandler;
internals.setSuspenseHandler = setSuspenseHandler;
// React Refresh
internals.findHostInstancesForRefresh = findHostInstancesForRefresh;
internals.scheduleRefresh = scheduleRefresh;
internals.scheduleRoot = scheduleRoot;
internals.setRefreshHandler = setRefreshHandler;
Expand Down
30 changes: 0 additions & 30 deletions packages/react-refresh/src/ReactFreshRuntime.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import type {
RefreshUpdate,
ScheduleRefresh,
ScheduleRoot,
FindHostInstancesForRefresh,
SetRefreshHandler,
} from 'react-reconciler/src/ReactFiberHotReloading';
import type {ReactNodeList} from 'shared/ReactTypes';
Expand All @@ -29,7 +28,6 @@ type Signature = {
};

type RendererHelpers = {
findHostInstancesForRefresh: FindHostInstancesForRefresh,
scheduleRefresh: ScheduleRefresh,
scheduleRoot: ScheduleRoot,
setRefreshHandler: SetRefreshHandler,
Expand Down Expand Up @@ -414,34 +412,6 @@ export function getFamilyByType(type: any): Family | void {
}
}

export function findAffectedHostInstances(
families: Array<Family>,
): Set<Instance> {
if (__DEV__) {
const affectedInstances = new Set<Instance>();
mountedRoots.forEach(root => {
const helpers = helpersByRoot.get(root);
if (helpers === undefined) {
throw new Error(
'Could not find helpers for a root. This is a bug in React Refresh.',
);
}
const instancesForRoot = helpers.findHostInstancesForRefresh(
root,
families,
);
instancesForRoot.forEach(inst => {
affectedInstances.add(inst);
});
});
return affectedInstances;
} else {
throw new Error(
'Unexpected call to React Refresh in a production environment.',
);
}
}

export function injectIntoGlobalHook(globalObject: any): void {
if (__DEV__) {
// For React Native, the global hook will be set up by require('react-devtools-core').
Expand Down
108 changes: 0 additions & 108 deletions packages/react-refresh/src/__tests__/ReactFresh-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3407,114 +3407,6 @@ describe('ReactFresh', () => {
}
});

it('can find host instances for a family', async () => {
if (__DEV__) {
await render(() => {
function Child({children}) {
return <div className="Child">{children}</div>;
}
$RefreshReg$(Child, 'Child');

function Parent({children}) {
return (
<div className="Parent">
<div>
<Child />
</div>
<div>
<Child />
</div>
</div>
);
}
$RefreshReg$(Parent, 'Parent');

function App() {
return (
<div className="App">
<Parent />
<Cls>
<Parent />
</Cls>
<Indirection>
<Empty />
</Indirection>
</div>
);
}
$RefreshReg$(App, 'App');

class Cls extends React.Component {
render() {
return this.props.children;
}
}

function Indirection({children}) {
return children;
}

function Empty() {
return null;
}
$RefreshReg$(Empty, 'Empty');

function Frag() {
return (
<>
<div className="Frag">
<div />
</div>
<div className="Frag">
<div />
</div>
</>
);
}
$RefreshReg$(Frag, 'Frag');

return App;
});

const parentFamily = ReactFreshRuntime.getFamilyByID('Parent');
const childFamily = ReactFreshRuntime.getFamilyByID('Child');
const emptyFamily = ReactFreshRuntime.getFamilyByID('Empty');

testFindHostInstancesForFamilies(
[parentFamily],
container.querySelectorAll('.Parent'),
);

testFindHostInstancesForFamilies(
[childFamily],
container.querySelectorAll('.Child'),
);

// When searching for both Parent and Child,
// we'll stop visual highlighting at the Parent.
testFindHostInstancesForFamilies(
[parentFamily, childFamily],
container.querySelectorAll('.Parent'),
);

// When we can't find host nodes, use the closest parent.
testFindHostInstancesForFamilies(
[emptyFamily],
container.querySelectorAll('.App'),
);
}
});

function testFindHostInstancesForFamilies(families, expectedNodes) {
const foundInstances = Array.from(
ReactFreshRuntime.findAffectedHostInstances(families),
);
expect(foundInstances.length).toEqual(expectedNodes.length);
foundInstances.forEach((node, i) => {
expect(node).toBe(expectedNodes[i]);
});
}

it('can update multiple roots independently', async () => {
if (__DEV__) {
// Declare the first version.
Expand Down

0 comments on commit 96b62ef

Please sign in to comment.