ignite-bowser
ignite-bowser copied to clipboard
Infinite rendering and infinite call to useEffect when checking store member length
When trying to do conditional check on model number of elements infinite rendering happens, and useEffects keeps running forever.
Sample code , notice renderList code if uncomment the // if(categoryStore && categoryStore.categories.length > 0) {
then useEffects will keep calling to infinite.
import * as React from "react"
import { observer } from "mobx-react-lite"
import { FlatList, SafeAreaView, TextStyle, View, ViewStyle, Alert } from "react-native"
import { ParamListBase } from "@react-navigation/native"
import { NativeStackNavigationProp } from "react-native-screens/native-stack"
import { Screen, Text, Header } from "../components"
import { useStores } from "../models/root-store"
import { color } from "../theme"
import { useEffect, useState } from "react"
export interface CategoryScreenProps {
navigation: NativeStackNavigationProp<ParamListBase>
}
const ROOT: ViewStyle = {
backgroundColor: color.palette.offWhite,
}
const ITEM_VIEW: ViewStyle = {
borderColor: color.palette.lightGrey,
borderWidth: 3,
padding: 20,
marginVertical: 8,
marginHorizontal: 16
}
const TITLE_TEXT: TextStyle = {
fontSize: 32,
color: color.palette.black,
textAlign: "center"
}
export const CategoryScreen: React.FunctionComponent<CategoryScreenProps> = observer((props) => {
const { categoryStore } = useStores()
const fetchCategories = () => {
categoryStore.getCategories()
}
const [refreshing, setRefreshing] = useState(false)
useEffect(() => {
setRefreshing(true)
console.tron.log("before fetchCategories ", categoryStore.categories.length)
fetchCategories()
console.tron.log("after fetchCategories ", categoryStore.categories.length)
setRefreshing(false)
})
const keyExtractor = item => String(item.id)
const onPressItem = (item) => {
props.navigation.navigate("list", {
category: item
})
}
const renderItem = ({ item }) => {
const { id, name} = item
return <View style={ITEM_VIEW}>
<Text style={TITLE_TEXT} onPress={() => onPressItem(id)}>{name}</Text>
</View>
}
const renderList = () => {
// if(categoryStore && categoryStore.categories.length > 0) {
return <FlatList
data={categoryStore.categories}
renderItem={renderItem}
numColumns={1}
keyExtractor={keyExtractor}
onRefresh={fetchCategories}
refreshing={refreshing}
/>
// }
}
return (
<View style={ROOT}>
<View>
<Text preset="header" tx="global.header" style={ { textAlign: "center", backgroundColor: "green", padding: 8 } } />
</View>
<SafeAreaView style={ { margin: 2 } }>
{renderList()}
</SafeAreaView>
</View>
)
})
Please advice what's the problem in this example?
@jamonholmgren @robinheinze if possible to help me in this.
thanks in advance!