I got a very huge FlatList which renders 800 buttons with an Image and a Text. This list is inside a TabScreen, which is inside a home screen with another tabScreen which has a textinput. When I change the text inside this textInput, the setState triggers my flatlist which under the hood updates, renders again its tons of items and slows everything. How can i avoid this?
Home Screen:
export default function HomeScreen(props: any) { const Tab = createBottomTabNavigator(); return (<View style={styles.home__container}><HeaderButton navigation={props.navigation} /><Tab.Navigator screenOptions={({ route }) => ({ tabBarIcon: ({ focused, color, size }) => { let iconName: string = ""; if (route.name === "Search") { iconName = "ios-search"; } else if (route.name === "List") { iconName = focused ? "ios-list-box" : "ios-list"; } return <Ionicons name={iconName} size={size} color={color} />; }, })} tabBarOptions={{ activeTintColor: "#ffcb05", inactiveTintColor: "#ffffff", style: { backgroundColor: "#2a75bb" }, }}><Tab.Screen name="Search" component={TabSearchScreen} /><Tab.Screen name="List" component={TabListScreen} /></Tab.Navigator><PokemonSavedContainer navigation={props.navigation} /></View> );}
FlatList Tab (TabListScreen) :
const TabListScreen = () => { const flatListRef = useRef<FlatList<{ name: string }>>(null); const scrollList = (index: number) => { if (flatListRef.current) flatListRef.current.scrollToIndex({ index: index }); }; const keyExtractor = (item: any) => `key-${item.name}`; const renderItem = (item: any) => { return (<MySwipeable pokeNumber={item.index + 1} pokeName={item.item.name} /> ); }; return (<View style={styles.pokedex__list}><FlatList data={pokedex} ref={flatListRef} renderItem={renderItem} keyExtractor={(item) => keyExtractor(item)} style={styles.pokedex__list__pokemons} onScrollToIndexFailed={() => alert("something went wrong")} getItemLayout={(data, index) => ({ length: 100, offset: 100 * index, index, })} /><View style={{ flexDirection: "column", marginTop: 20 }}><SmallButton onPress={() => scrollList(0)} title="Kanto" /><SmallButton onPress={() => scrollList(151)} title="Jhoto" /><SmallButton onPress={() => scrollList(251)} title="Hoenn" /><SmallButton onPress={() => scrollList(386)} title="Sinnoh" /><SmallButton onPress={() => scrollList(494)} title="Unova" /><SmallButton onPress={() => scrollList(649)} title="Kalos" /><SmallButton onPress={() => scrollList(721)} title="Alola" /><SmallButton onPress={() => scrollList(809)} title="Galar" /></View></View> );};export default TabListScreen;
textInput Screen (TabSearch Screen):
export default function TabSearchScreen() { const pokemonState = useSelector((state: RootStore) => state.pokemon); return (<View style={styles.home__container}><Searchbar /> {pokemonState.pokemon && <PokeContainer />}</View> );}
Search Component
export default function Searchbar() { const dispatch = useDispatch(); const handleSubmit = () => { dispatch(GetPokemon(pokemonName)); }; const [pokemonName, setPokemonName] = useState(""); return (<View style={styles.home__search}><TextInput style={styles.home__search__textInput} onChangeText={(value) => setPokemonName(value)} value={pokemonName} /><PokeBallButton title="search" onPress={handleSubmit} /></View> );}
FlatList Item (called Myswipeable because i want to give it swipe functionality)
export interface MySwipeProps { children?: React.ReactNode; props?: any; pokeName: string; pokeNumber: number;}const MySwipeable: React.FC<MySwipeProps> = ({ children, pokeName, pokeNumber, ...props}) => { console.log("pokemon"); const renderLeftActions = () => { return <Animated.View></Animated.View>; }; return (<Swipeable renderLeftActions={renderLeftActions}><View style={styles.button__list__container}><Image source={{ uri: `https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${pokeNumber}.png`, }} style={styles.pokemonTiny} /><Text style={styles.button__list__text}>{pokeName}</Text></View></Swipeable> );};export default MySwipeable;