I want to load the list of all users from an endpoint on the first load of the app.
But, I am getting the Too many re-renders. React limits the number of renders to prevent an infinite loop.
error while running this code.
It was working expected with a json object but I replace json with endpoint then I start getting this. My code is:-
export default function App() {
const [profiles, setProfiles] = useState()
const [loader, setLoader] = useState()
setLoader(false)
const getProfiles = async () => {
console.log('start')
const res = await fetch("https://reqres.in/api/users?page=1")
const result = await res.json()
if(result != 'undefined') {
setProfiles(result.data)
setLoader(true)
}
}
useEffect(() => {
getProfiles();
}, []);
return (
<View style={styles.container}>
<ScrollView
contentContainerStyle={{
flexGrow: 1
}}
keyboardShouldPersistTaps='handled'
>
<View style={styles.tasksWrapper}>
<Text style={styles.sectionTitle}>Users List</Text>
<View style={styles.items}>
{
loader &&
profiles.map((profile, index) => {
setLoader(false)
return (
<TouchableOpacity key={index} onPress={() => completeTask(index)}>
<UserList profile={profile} />
</TouchableOpacity>
)
})
}
</View>
</View>
</ScrollView>
</View>
);
}
CodePudding user response:
You are calling setLoader(false)
in the render function. That causes the error.
You can set the initial state like this:
const [loader, setLoader] = useState(false);
CodePudding user response:
You made a mistake
setLoader(false)
remove this and use like
const [loader, setLoader] = useState(false)
And your function should be
const getProfiles = async () => {
setLoader(true)
console.log('start')
const res = await fetch("https://reqres.in/api/users?page=1")
const result = await res.json()
if(result != 'undefined') {
setProfiles(result.data)
}
setLoader(false)
}
CodePudding user response:
Hey you should never call setSTate inside render methods:
import * as React from 'react';
import { Text, View, StyleSheet ,ScrollView,TouchableOpacity} from 'react-native';
import Constants from 'expo-constants';
export default function App() {
const [profiles, setProfiles] = React.useState([])
const [loader, setLoader] = React.useState(true)
const getProfiles = React.useCallback(async () => {
const res = await fetch("https://reqres.in/api/users?page=1")
const result = await res.json()
if(result != 'undefined') {
setProfiles(result.data)
setLoader(false)
}
},[])
React.useEffect(() => {
getProfiles();
}, [getProfiles]);
return (
<View style={styles.container}>
<ScrollView
contentContainerStyle={{
flexGrow: 1
}}
keyboardShouldPersistTaps='handled'
>
<View style={styles.tasksWrapper}>
{loader && <Text>Loading</Text>}
<Text style={styles.sectionTitle}>Users List</Text>
<View style={styles.items}>
{
!loader && profiles.map((profile, index) => {
return (
<TouchableOpacity key={index} onPress={() => completeTask(index)}>
<Text>{index}</Text>
</TouchableOpacity>
)
})
}
</View>
</View>
</ScrollView>
</View>
);
}
const styles = StyleSheet.create({
container:{flex:1,justifyContent:'center',alignItems:'center',paddingTop:100}
})
Try this code :
ive removed all set state methods from render. here is a working example Expo link
Hope it helps. feel free for doubts