-
-
Notifications
You must be signed in to change notification settings - Fork 447
Open
Description
Hi! 👋
Thanks for your work on this project!
Summary
When using NestableScrollContainer + NestableDraggableFlatList (one per section), React Native logs this warning once per nested list:
Warning: ref.measureLayout must be called with a ref to a native component.
This appears to be caused by calling measureLayout with a findNodeHandle(...) result (a node handle number) instead of a native component ref. Passing the scrollableRef.current directly fixes the warning.
I patched react-native-draggable-flatlist@4.0.3 via patch-package as a workaround.
Patch (diff)
diff --git a/node_modules/react-native-draggable-flatlist/src/components/NestableDraggableFlatList.tsx b/node_modules/react-native-draggable-flatlist/src/components/NestableDraggableFlatList.tsx
index 1559352..2ab50ad 100644
--- a/node_modules/react-native-draggable-flatlist/src/components/NestableDraggableFlatList.tsx
+++ b/node_modules/react-native-draggable-flatlist/src/components/NestableDraggableFlatList.tsx
@@ -1,8 +1,8 @@
import React, { useRef, useState } from "react";
-import { findNodeHandle, LogBox } from "react-native";
+import { LogBox } from "react-native";
import Animated, {
- useDerivedValue,
- useSharedValue,
+ useDerivedValue,
+ useSharedValue,
} from "react-native-reanimated";
import { DraggableFlatListProps } from "../types";
import DraggableFlatList from "../components/DraggableFlatList";
@@ -13,97 +13,99 @@ import { useStableCallback } from "../hooks/useStableCallback";
import { FlatList } from "react-native-gesture-handler";
function NestableDraggableFlatListInner<T>(
- props: DraggableFlatListProps<T>,
- ref?: React.ForwardedRef<FlatList<T>>
+ props: DraggableFlatListProps<T>,
+ ref?: React.ForwardedRef<FlatList<T>>
) {
- const hasSuppressedWarnings = useRef(false);
+ const hasSuppressedWarnings = useRef(false);
- if (!hasSuppressedWarnings.current) {
- LogBox.ignoreLogs([
- "VirtualizedLists should never be nested inside plain ScrollViews with the same orientation because it can break windowing",
- ]); // Ignore log notification by message
- //@ts-ignore
- console.reportErrorsAsExceptions = false;
- hasSuppressedWarnings.current = true;
- }
+ if (!hasSuppressedWarnings.current) {
+ LogBox.ignoreLogs([
+ "VirtualizedLists should never be nested inside plain ScrollViews with the same orientation because it can break windowing",
+ ]); // Ignore log notification by message
+ //@ts-ignore
+ console.reportErrorsAsExceptions = false;
+ hasSuppressedWarnings.current = true;
+ }
- const {
- scrollableRef,
- outerScrollOffset,
- setOuterScrollEnabled,
- } = useSafeNestableScrollContainerContext();
+ const {
+ scrollableRef,
+ outerScrollOffset,
+ setOuterScrollEnabled,
+ } = useSafeNestableScrollContainerContext();
- const listVerticalOffset = useSharedValue(0);
- const [animVals, setAnimVals] = useState({});
- const defaultHoverOffset = useSharedValue(0);
- const [listHoverOffset, setListHoverOffset] = useState(defaultHoverOffset);
+ const listVerticalOffset = useSharedValue(0);
+ const [animVals, setAnimVals] = useState({});
+ const defaultHoverOffset = useSharedValue(0);
+ const [listHoverOffset, setListHoverOffset] = useState(defaultHoverOffset);
- const hoverOffset = useDerivedValue(() => {
- return listHoverOffset.value + listVerticalOffset.value;
- }, [listHoverOffset]);
+ const hoverOffset = useDerivedValue(() => {
+ return listHoverOffset.value + listVerticalOffset.value;
+ }, [listHoverOffset]);
- useNestedAutoScroll({
- ...animVals,
- hoverOffset,
- });
+ useNestedAutoScroll({
+ ...animVals,
+ hoverOffset,
+ });
- const onListContainerLayout = useStableCallback(async ({ containerRef }) => {
- const nodeHandle = findNodeHandle(scrollableRef.current);
+ const onListContainerLayout = useStableCallback(async ({ containerRef }) => {
+ const scrollNode = scrollableRef.current;
+ const containerNode = containerRef.current;
- const onSuccess = (_x: number, y: number) => {
- listVerticalOffset.value = y;
- };
- const onFail = () => {
- console.log("## nested draggable list measure fail");
- };
- //@ts-ignore
- containerRef.current.measureLayout(nodeHandle, onSuccess, onFail);
- });
+ if (!scrollNode || !containerNode) return;
- const onDragBegin: DraggableFlatListProps<T>["onDragBegin"] = useStableCallback(
- (params) => {
- setOuterScrollEnabled(false);
- props.onDragBegin?.(params);
- }
- );
+ const onSuccess = (_x: number, y: number) => {
+ listVerticalOffset.value = y;
+ };
+ const onFail = () => {
+ console.log("## nested draggable list measure fail");
+ };
+ containerNode.measureLayout(scrollNode, onSuccess, onFail);
+ });
- const onDragEnd: DraggableFlatListProps<T>["onDragEnd"] = useStableCallback(
- (params) => {
- setOuterScrollEnabled(true);
- props.onDragEnd?.(params);
- }
- );
+ const onDragBegin: DraggableFlatListProps<T>["onDragBegin"] = useStableCallback(
+ (params) => {
+ setOuterScrollEnabled(false);
+ props.onDragBegin?.(params);
+ }
+ );
- const onAnimValInit: DraggableFlatListProps<T>["onAnimValInit"] = useStableCallback(
- (params) => {
- setListHoverOffset(params.hoverOffset);
- setAnimVals({
- ...params,
- hoverOffset,
- });
- props.onAnimValInit?.(params);
- }
- );
+ const onDragEnd: DraggableFlatListProps<T>["onDragEnd"] = useStableCallback(
+ (params) => {
+ setOuterScrollEnabled(true);
+ props.onDragEnd?.(params);
+ }
+ );
+
+ const onAnimValInit: DraggableFlatListProps<T>["onAnimValInit"] = useStableCallback(
+ (params) => {
+ setListHoverOffset(params.hoverOffset);
+ setAnimVals({
+ ...params,
+ hoverOffset,
+ });
+ props.onAnimValInit?.(params);
+ }
+ );
- return (
- <DraggableFlatList
- ref={ref}
- onContainerLayout={onListContainerLayout}
- activationDistance={props.activationDistance || 20}
- scrollEnabled={false}
- {...props}
- outerScrollOffset={outerScrollOffset}
- onDragBegin={onDragBegin}
- onDragEnd={onDragEnd}
- onAnimValInit={onAnimValInit}
- />
- );
+ return (
+ <DraggableFlatList
+ ref={ref}
+ onContainerLayout={onListContainerLayout}
+ activationDistance={props.activationDistance || 20}
+ scrollEnabled={false}
+ {...props}
+ outerScrollOffset={outerScrollOffset}
+ onDragBegin={onDragBegin}
+ onDragEnd={onDragEnd}
+ onAnimValInit={onAnimValInit}
+ />
+ );
}
// Generic forwarded ref type assertion taken from:
// https://fettblog.eu/typescript-react-generic-forward-refs/#option-1%3A-type-assertion
export const NestableDraggableFlatList = React.forwardRef(
- NestableDraggableFlatListInner
+ NestableDraggableFlatListInner
) as <T>(
- props: DraggableFlatListProps<T> & { ref?: React.ForwardedRef<FlatList<T>> }
+ props: DraggableFlatListProps<T> & { ref?: React.ForwardedRef<FlatList<T>> }
) => ReturnType<typeof NestableDraggableFlatListInner>;Metadata
Metadata
Assignees
Labels
No labels