Home > Enterprise >  Flatlist inside tab navigator is scrolling to top on state change in react native
Flatlist inside tab navigator is scrolling to top on state change in react native

Time:02-11

Here you can see the gif

Here is my whole Navigator functional component. I'm trying to implement two tabs using Tab Navigator. One to display the cryptos and the other to display the forex data.

The problem is, when I try to load more data on reaching the flatlist's end, the flatlist is scrolling to the top since I'm making a state change [page 1].

const Navigator = () => {    
  const Tab = createMaterialTopTabNavigator();

  const renderItems = ({ item }) => (
    <Text>{item.name}<Text>
  );  

  const fetchMarketData = async () => {
    console.log("Fetching");
    const marketData = await getCryptoMarketData({ page });
    if (marketData != "Network Error") {
      const ids = data.map((item) => item.id);
      let newData = marketData.filter((item) => !ids.includes(item.id));
      setData([...data, ...newData]);
      setFetching(false);
    } else {
      setFetching(false);
      Alert.alert(marketData, "Sorry for the inconvenience");
    }
  };

  useEffect(() => {
    setFetching(true);
    const data = async () => {
      await fetchMarketData();
    };
  }, [page]);

  const handleLoadMore = async () => {
    setFetching(true);
    setPage((page) => page   1);
  };

  const ScreenA = () => (
    <FlatList
      data={data}
      style={{ backgroundColor: "white" }}
      keyExtractor={(item) => item.id}
      renderItem={renderItems}
      scrollEventThrottle={16}
      onEndReached={handleLoadMore}
      onEndReachedThreshold={0}
    />
  );  

  return (
    <Tab.Navigator
      screenOptions={({ route }) => screenOptions(route)}
      keyboardDismissMode="auto"
    >
      <Tab.Screen name="Crypto" component={ScreenA} />
      <Tab.Screen name="Forex" component={ScreenC} />
    </Tab.Navigator>
  );
};

export default Navigator;

OnEndReached is firing the handleLoadMore function and after the state change on data, the Flatlist is scrolling to the top.

CodePudding user response:

1st reason

  • you have typo in "fetchMarketData", how exactly u get "newData" because i cant see it anywhere, maybe it should be "marketData" if not then u adding SAME old data PLUS undefined[...data, ...undefined]

2nd reason

reason why is that u call setPage(page 1) and then "fetchMarketData" this is bad why ? because setState is async and it can be changed instant or after 5 secound, so u dont know when its changed and this is why we have hooks, you can use "useEffect" to handle this

change your "handleLoadMore" for example like this

const handleLoadMore = () => {
    setPage(page   1);
  };

add useEffect hook that runs when "page" state changes

React.useEffect(() => {
 (async() => {
    setFetching(true)
    const marketData = await getCryptoMarketData({ page });
    if (marketData != "Network Error") {
      setData([...data, ...marketData]);
    } else {
      Alert.alert(marketData, "Sorry for the inconvenience");
    }
    setFetching(false)
})()
}, [page])
  • Related