我有一个非常庞大的FlatList,其中包含800个带有图像和文本的按钮。此列表位于TabScreen内部,该TabScreen位于主屏幕中,而另一个tabText具有文本输入。当我在textInput中更改文本时,setState会触发我的平面列表,该列表将在幕后进行更新,再次呈现其大量项目并减慢一切。我如何避免这种情况?
主屏幕:
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标签(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;
文本输入屏幕(标签搜索屏幕):
export default function TabSearchScreen() {
const pokemonState = useSelector((state: RootStore) => state.pokemon);
return (
<View style={styles.home__container}>
<Searchbar />
{pokemonState.pokemon && <PokeContainer />}
</View>
);
}
搜索组件
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项(之所以称为Myswipeable,是因为我想为其提供滑动功能)
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;
答案 0 :(得分:0)
尝试使用React.memo()防止平面列表重新呈现。
这是一篇很有帮助的文章,解释了什么是React.memo()以及如何使用它。