Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"no container to recycle" and maintainVisibleContentPosition issues #125

Open
skaionedev opened this issue Mar 6, 2025 · 9 comments
Open

Comments

@skaionedev
Copy link

I'm trying to render LegendList inside TrueSheet and having this issues

Image
Image

@michbil
Copy link
Contributor

michbil commented Mar 6, 2025

@skaionedev Cannot read property 'coordinate' may be fixed by the #118
Interesting that you have 1500 containers allocated. What's your estimatedItemSize ?

@skaionedev
Copy link
Author

@michbil I've dynamic height items and my estimated size is 150 px

@skaionedev
Copy link
Author

@michbil and I couldn't make onReachEnd work properly. It would fire only once and right when sheet opens

@hirbod
Copy link

hirbod commented Mar 6, 2025

onEndReached is indeed buggy for me as well, but I could fix it with
onEndReachedThreshold={0.1}

Without a small threshold, it would already fire onEndReach right at the beginning and it will also not reset when scrolling back up. This small value works really well though.

@michbil
Copy link
Contributor

michbil commented Mar 6, 2025

@skaionedev Could you provide code snippet, at least partially how do you use LegendList inside TrueSheet?

@michbil
Copy link
Contributor

michbil commented Mar 6, 2025

onEndReached is indeed buggy for me as well, but I could fix it with onEndReachedThreshold={0.1}

Without a small threshold, it would already fire onEndReach right at the beginning and it will also not reset when scrolling back up. This small value works really well though.

@hirbod Should we have some sort of minimal list length, at which we should disable onStartReached/onEndReached handlers to avoid misfire of those events?

@hirbod
Copy link

hirbod commented Mar 6, 2025

Yeah, onEndReach should definitely not fire right after data is added. It should actually scroll, I guess.

I just figured out that on Android, 0.1 wasn’t even enough—I had to set it to 0.03, lol.

Now it doesn’t fire on load and also resets when scrolling all the way down and back up. I think there’s some logic issue or bug.

@skaionedev
Copy link
Author

@michbil

import { TrueSheet } from "@lodev09/react-native-true-sheet";
import { useRef } from "react";
import { TouchableOpacity, View } from "react-native";
import { Text } from "~/shared/ui";

const items = []; // mock data, in my app I'm using Bible verses in references list( from 1 - 8k items)

export const Test = () => {
  const sheetRef = useRef<TrueSheet>(null);

  return (
    <>
      <View>
        <TouchableOpacity>
          <Text>open sheet</Text>
        </TouchableOpacity>
      </View>

      <TrueSheet sizes={['large']} ref={sheetRef}>
        <LegendList
          data={items}
          renderItem={({ item }) => (
//item height should be dynamic
            <View>
              <Text>{item.title}</Text>
              <Text>{item.description}</Text>
            </View>
          )}
          estimatedItemSize={150}
          recycleItems
        />
      </TrueSheet>
    </>
  );
};

@michbil
Copy link
Contributor

michbil commented Mar 8, 2025

@skaionedev It looks like LegendList is trying to get a really lot of the space inside of TrueSheet
My onLayout is showing initial size around 6000 pixels, which is really a lot
onlayout {"height": 6067.66650390625, "width": 393, "x": 0, "y": 0}

From the true sheet documentation, it says it doesn't really work well with flex:1 layouts, and LegendList requires to know your window height to work correctly.

@jmeistrich Any idea how to make it work?

Only way for me to make it work somehow properly is to remove scrollRef={scrollview} and assign fixed height to the LegendList.

FYI my test rig for the issue.

import { LegendList, type LegendListRef } from "@legendapp/list";
import { TrueSheet } from "@lodev09/react-native-true-sheet";
import { useCallback, useRef } from "react";
import { type LayoutChangeEvent, Text, TouchableOpacity, View } from "react-native";
import type { ScrollView } from "react-native-gesture-handler";

const randomNames = [
    "Alex Thompson",
    "Jordan Lee",
    "Sam Parker",
    "Taylor Kim",
    "Morgan Chen",
    "Riley Zhang",
    "Casey Williams",
    "Quinn Anderson",
    "Blake Martinez",
    "Avery Rodriguez",
    "Drew Campbell",
    "Jamie Foster",
    "Skylar Patel",
    "Charlie Wright",
    "Sage Mitchell",
    "River Johnson",
    "Phoenix Garcia",
    "Jordan Taylor",
    "Reese Cooper",
    "Morgan Bailey",
];

// Array of lorem ipsum sentences to randomly choose from
const loremSentences = [
    "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
    "Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
    "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.",
    "Duis aute irure dolor in reprehenderit in voluptate velit esse.",
    "Excepteur sint occaecat cupidatat non proident, sunt in culpa.",
    "Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit.",
    "Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet.",
    "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
    "Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
    "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.",
    "Duis aute irure dolor in reprehenderit in voluptate velit esse.",
    "Excepteur sint occaecat cupidatat non proident, sunt in culpa.",
    "Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit.",
    "Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet.",
];

// Generate mock items with random names and lorem text
const items = Array.from({ length: 50 }, () => ({
    title: randomNames[Math.floor(Math.random() * randomNames.length)],
    description: loremSentences[Math.floor(Math.random() * loremSentences.length)],
}));

const Test = () => {
    const sheetRef = useRef<TrueSheet>(null);
    const onLayout = useCallback((event: LayoutChangeEvent) => {
        console.log("onlayout", event.nativeEvent.layout);
    }, []);

    const scrollview = useRef<ScrollView>(null);
    const ll = useRef<LegendListRef>(null);

    return (
        <>
            <View>
                <TouchableOpacity onPress={() => sheetRef.current?.present()}>
                    <Text>open sheet</Text>
                </TouchableOpacity>
            </View>

            <TrueSheet sizes={["large"]} ref={sheetRef} scrollRef={scrollview}>
                <LegendList
                    nestedScrollEnabled
                    ref={(ref) => {
                        scrollview.current = ref?.getNativeScrollRef();
                    }}
                    data={items}
                    renderItem={({ item }) => (
                        //item height should be dynamic
                        <View style={{ padding: 10 }}>
                            <Text>{item.title}</Text>
                            <Text>{item.description}</Text>
                        </View>
                    )}
                    estimatedItemSize={150}
                    recycleItems
                    onLayout={onLayout}
                />
            </TrueSheet>
        </>
    );
};

export default Test;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants