Migrating from Component State to Hooks for a Fetch Request
This tutorial was originally published on React Native School. If you're interested in learning more about React Native checkout our library of 80+ lessons!
Hooks are the latest hotness in React Native. Now that they're part of React Native core how can this change your code?
Starting Code
import React from 'react';
import {
StyleSheet,
Text,
View,
FlatList,
SafeAreaView,
ActivityIndicator,
Button,
} from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
export default class App extends React.Component {
state = {
people: [],
loading: true,
page: 1,
};
componentDidMount() {
this.getPeople();
}
getPeople = () => {
this.setState({ loading: true });
fetch(`https:swapi.co/api/people?page=${this.state.page}`)
.then(res => res.json())
.then(res => {
this.setState(state => ({
people: [...state.people, ...res.results],
loading: false,
}));
});
};
render() {
return (
<SafeAreaView style={{ flex: 1 }}>
<FlatList
data={this.state.people}
keyExtractor={item => item.url}
renderItem={({ item }) => (
<View>
<Text>{item.name}</Text>
</View>
)}
ListFooterComponent={
this.state.loading ? (
<ActivityIndicator />
) : (
<Button
title="Load More"
onPress={() => {
this.setState(
state => ({ page: state.page + 1 }),
this.getPeople
);
}}
/>
)
}
/>
</SafeAreaView>
);
}
}
Finished Code
const useSwapiPeople = () => {
const [people, setPeople] = useState([]);
const [loading, setLoading] = useState(false);
const [page, setPage] = useState(1);
useEffect(
() => {
setLoading(true);
fetch(`https:swapi.co/api/people?page=${page}`)
.then(res => res.json())
.then(res => {
setPeople([...people, ...res.results]);
setLoading(false);
});
},
[page]
);
const loadMore = () => {
setPage(page + 1);
};
return {
people,
loading,
loadMore,
};
};
export default () => {
const { people, loading, loadMore } = useSwapiPeople();
return (
<SafeAreaView style={{ flex: 1 }}>
<FlatList
data={people}
keyExtractor={item => item.url}
renderItem={({ item }) => (
<View>
<Text>{item.name}</Text>
</View>
)}
ListFooterComponent={
loading ? (
<ActivityIndicator />
) : (
<Button title="Load More" onPress={loadMore} />
)
}
/>
</SafeAreaView>
);
};