1

so i want to load some data from my server using axios in React native. The data was retrieved successfully, but i don't know how to display it on the page. When i click button 'Load students' it does axios get method and after that calls method 'showStudents' but that method doesn't return anything. I really don't understand how rendering works in react native so i would appreciate any help and guidance. Also if there is easier way to do all of this, i'm open for suggestions.

export default function Students() {
const [s, setStudents] = useState('')

const getStudents = async () => {
    try{
        const {data: {students}} = await axios.get('http://192.168.1.2:3000/api/v1/students')
        setStudents(students)
        //console.log(students)
        showStudents()
    }
    catch(error){
        console.log(error)
    }
}

const showStudents = () => {
    
    return( <ScrollView>
            {
                s.map((student) => (
                    <ListItem key={student._id} bottomDivider>
                        <ListItem.Content>
                            <ListItem.Title>{student.firstName}</ListItem.Title>
                            <ListItem.Subtitle>{student.index}</ListItem.Subtitle>
                        </ListItem.Content>
                    </ListItem>
                ))
            }
        </ScrollView>)
    
}


return (
    <View style={styles.container}>
        <Button title='Load students' color='green' onPress={getStudents}/>
    </View>
);

}

1 Answer 1

3

The function showStudents returns a JSX component, but not inside of the render function of the component Students.

You can just create a new JSX component and use conditional rendering in order to render it whenever the state s (I would call it students) is not undefined and has a length strictly greater than zero.

const [students, setStudents] = useState()

const getStudents = async () => {
    try{
        const {data: {students}} = await axios.get('http://192.168.1.2:3000/api/v1/students')
        setStudents(students)
    }
    catch(error){
        console.log(error)
    }
}

return (
    <View style={styles.container}>
        <Button title='Load students' color='green' onPress={getStudents}/>
        {
            students && students.length > 0 ? <ScrollView>
            {
                students.map((student) => (
                    <ListItem key={student._id} bottomDivider>
                        <ListItem.Content>
                            <ListItem.Title>{student.firstName}</ListItem.Title>
                            <ListItem.Subtitle>{student.index}</ListItem.Subtitle>
                        </ListItem.Content>
                    </ListItem>
                ))
            }
           </ScrollView> : null
        }
    </View>
);

We could create a new component to make things more structured. Let us introduce StudentList.

export function StudentList({students}) {
    return <ScrollView>
            {
                students.map((student) => (
                    <ListItem key={student._id} bottomDivider>
                        <ListItem.Content>
                            <ListItem.Title>{student.firstName}</ListItem.Title>
                            <ListItem.Subtitle>{student.index}</ListItem.Subtitle>
                        </ListItem.Content>
                    </ListItem>
                ))
            }
           </ScrollView> 
}

Then, reuse this new component.

const [students, setStudents] = useState()

const getStudents = async () => {
    try{
        const {data: {students}} = await axios.get('http://192.168.1.2:3000/api/v1/students')
        setStudents(students)
    }
    catch(error){
        console.log(error)
    }
}

return (
    <View style={styles.container}>
        <Button title='Load students' color='green' onPress={getStudents}/>
        {
            students && students.length > 0 ? <StudentList students={students} /> : null
        }
    </View>
);
Sign up to request clarification or add additional context in comments.

6 Comments

Great, that works. Thank you so much for your help. Also another question regarding this, is there any way i could fetch data when i load this page without pressing the button? I read something about using useEffect method but if it's possible can you explain what that does?
Yes, this is possible. Create an effect with an empty dependency array, then it will be called on mount of the component. Check the answers for this question to get an idea. But check the accepted answer, and do not use some third party lib as suggested by others.
I have tried using useEffect for the the question you've given me but when i open that page(i put log inside) is calls my fetch function infinite times. Is there any ways i can fix this? const getStudents = useCallback(async () => { try{ const {data: {students}} = await axios.get('http://192.168.1.2:3000/api/v1/students') setStudents(students) } catch(error){ console.log(error) } }, [students]) useEffect(() => { console.log('asd') getStudents() }, [getStudents])
students from the axis response is unrelated to the students state. You need to remove students from the dependency array. Leave it empty: React.useEffect(() => { .... setStudents(students) }, [])
It fiexs that part, but what do i have to do to make it so that when i add/update a student in my database and get back on the page where it fetches all students again because there was a change. Again i read that dependency array has soemthing to do with that(maybe i'm wrong) but i tried every scenario i could think of and it doesn't work.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.