-
-
Notifications
You must be signed in to change notification settings - Fork 980
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Web] Remove
findNodeHandle
function. (#3127)
## Description `findNodeHandle` is a utility function that allows us to get native view from React component. The problem is, that under the hood it uses `findDOMNode`, which is deprecated and [will be removed in React 19](https://react.dev/reference/react-dom/findDOMNode). To get rid of this function, I've written our implementation that meets our requirements. Also, for new API we had to introduce a little trick (thanks @j-piasecki) - we add wrapper `div` with `display: contents;` style and we pass a ref to this element. With that change, it is much easier to get required `HTMLElement` - we simply have to get `div` from `ref` and find first child (preferably the one without `display: contents;`) >[!WARNING] > You may find tat in `StrictMode` most of new API examples doesn't work. That's not really the case. If you check example from [this comment](#3127 (comment)) it works fine. What really don't work in these examples are the animations. ## Test plan Tested that example app works and no `findNodeHandle` error is thrown in `StrictMode`
- Loading branch information
Showing
8 changed files
with
84 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { findNodeHandle } from 'react-native'; | ||
|
||
export default findNodeHandle; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
type GestureHandlerRef = { | ||
viewTag: GestureHandlerRef; | ||
current: HTMLElement; | ||
}; | ||
|
||
export default function findNodeHandle( | ||
viewRef: GestureHandlerRef | HTMLElement | ||
): HTMLElement | number { | ||
// Old API assumes that child handler is HTMLElement. | ||
// However, if we nest handlers, we will get ref to another handler. | ||
// In that case, we want to recursively call findNodeHandle with new handler viewTag (which can also be ref to another handler). | ||
if ((viewRef as GestureHandlerRef)?.viewTag !== undefined) { | ||
return findNodeHandle((viewRef as GestureHandlerRef).viewTag); | ||
} | ||
|
||
if (viewRef instanceof HTMLElement) { | ||
if (viewRef.style.display === 'contents') { | ||
return findNodeHandle(viewRef.firstChild as HTMLElement); | ||
} | ||
|
||
return viewRef; | ||
} | ||
|
||
// In new API, we receive ref object which `current` field points to wrapper `div` with `display: contents;`. | ||
// We want to return the first descendant (in DFS order) that doesn't have this property. | ||
let element = viewRef?.current; | ||
|
||
while (element && element.style.display === 'contents') { | ||
element = element.firstChild as HTMLElement; | ||
} | ||
|
||
return element; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import React, { forwardRef } from 'react'; | ||
import type { LegacyRef, PropsWithChildren } from 'react'; | ||
import { tagMessage } from '../../../utils'; | ||
|
||
export const Wrap = forwardRef<HTMLDivElement, PropsWithChildren<{}>>( | ||
({ children }, ref) => { | ||
try { | ||
// I don't think that fighting with types over such a simple function is worth it | ||
// The only thing it does is add 'collapsable: false' to the child component | ||
// to make sure it is in the native view hierarchy so the detector can find | ||
// correct viewTag to attach to. | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const child: any = React.Children.only(children); | ||
|
||
const clone = React.cloneElement( | ||
child, | ||
{ collapsable: false }, | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access | ||
child.props.children | ||
); | ||
|
||
return ( | ||
<div | ||
ref={ref as LegacyRef<HTMLDivElement>} | ||
style={{ display: 'contents' }}> | ||
{clone} | ||
</div> | ||
); | ||
} catch (e) { | ||
throw new Error( | ||
tagMessage( | ||
`GestureDetector got more than one view as a child. If you want the gesture to work on multiple views, wrap them with a common parent and attach the gesture to that view.` | ||
) | ||
); | ||
} | ||
} | ||
); | ||
|
||
// On web we never take a path with Reanimated, | ||
// therefore we can simply export Wrap | ||
export const AnimatedWrap = Wrap; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters