My FeedDiscussionsHeadless CMS
New
Sign in
Log inSign up
Learn more about Hashnode Headless CMSHashnode Headless CMS
Collaborate seamlessly with Hashnode Headless CMS for Enterprise.
Upgrade ✨Learn more

Migrating from Component State to Hooks for a Fetch Request

Spencer Carli's photo
Spencer Carli
·Apr 17, 2019

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>
  );
};