DEV Community

Emerson Vieira
Emerson Vieira

Posted on

Consumindo API GraphQL usando React Native e Apollo Client

Image description

No tutorial de hoje, iremos consumir uma API GraphQL usando React Native e Apollo Client.

A API GraphQL será a seguinte: https://rickandmortyapi.com/graphql

Vamos à prática!

Crie um projeto usando npx react-native init NomeProjeto e após isso adicione as dependências abaixo

yarn add graphql @apollo/client@3.2.5
Enter fullscreen mode Exit fullscreen mode

Observação: @apollo/client@3.2.5 essa versão específica pois há um bug nas versões mais novas que impede o pleno funcionamento da mesma no RN.

Estrutura do projeto

Image description

Editar o arquivo metro.config.js como no exemplo abaixo

/**
 * Metro configuration for React Native
 * https://github.com/facebook/react-native
 *
 * @format
 */
const { getDefaultConfig } = require("metro-config");
const { resolver: defaultResolver } = getDefaultConfig.getDefaultValues();

module.exports = {
  resolver: {
    ...defaultResolver,
    sourceExts: [...defaultResolver.sourceExts, "cjs"],
  },
  transformer: {
    getTransformOptions: async () => ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: true,
      },
    }),
  },
};
Enter fullscreen mode Exit fullscreen mode

src/service/index.js

import { ApolloClient, InMemoryCache } from "@apollo/client";

const client = new ApolloClient({
  uri: "https://rickandmortyapi.com/graphql",
  cache: new InMemoryCache(),
});

export default client;
Enter fullscreen mode Exit fullscreen mode

src/queries/index.js

import { gql } from "@apollo/client";

const INFO_PERSON = gql`
  query {
    characters {
      results {
        id
        name
        gender
        image
      }
    }
  }
`;

export default INFO_PERSON;
Enter fullscreen mode Exit fullscreen mode

src/App.js

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */

import React from "react";

import Home from "./src/screens/Home";

import { ApolloProvider } from "@apollo/client";

import client from "./src/service/index";

const App = () => {
  return (
    <ApolloProvider client={client}>
      <Home />
    </ApolloProvider>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

/src/screens/Home.js

import React from "react";
import { View, Text, FlatList } from "react-native";
import { useQuery } from "@apollo/client";
import INFO_PERSON from "../queries";

import Card from "../components/Card";

const Home = () => {
  const { loading, error, data } = useQuery(INFO_PERSON);

  return (
    <View>
      {loading && <Text>Loading...</Text>}
      {error && <Text>Error! {error.message}</Text>}
      {data && (
        <FlatList
          data={data.characters.results}
          renderItem={({ item }) => <Card card={item} />}
          keyExtractor={(item) => item.id}
        />
      )}
    </View>
  );
};

export default Home;
Enter fullscreen mode Exit fullscreen mode

src/components/Card/index.js

import React from "react";
import { View, Text, Image } from "react-native";
import styles from "./styles";

const Card = ({ card }) => (
  <View activeOpacity={1} style={styles.card}>
    <Image
      style={styles.image}
      source={{ uri: card.image }}
      resizeMode="contain"
    />
    <View style={styles.imageDescriptionContainer}>
      <Text style={styles.text}>{`${card.name}, ${card.gender}`}</Text>
    </View>
  </View>
);

export default Card;
Enter fullscreen mode Exit fullscreen mode

src/components/Card/styles.js

import { StyleSheet, Dimensions } from "react-native";
const { height } = Dimensions.get("window");

export default StyleSheet.create({
  card: {
    height: height - 300,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "#fff",
    borderRadius: 5,
    shadowColor: "#000",
    shadowOffset: {
      width: 0,
      height: 2,
    },
    shadowRadius: 6,
    shadowOpacity: 0.3,
    elevation: 2,
    marginBottom: 2,
  },
  image: {
    borderRadius: 2,
    flex: 1,
    width: "100%",
    borderColor: "#000",
  },
  imageDescriptionContainer: {
    justifyContent: "flex-end",
    alignItems: "flex-start",
    flexDirection: "column",
    height: "100%",
    position: "absolute",
    left: 10,
    bottom: 10,
  },
  text: {
    textAlign: "center",
    fontSize: 20,
    color: "#fff",
    fontFamily: "Avenir",
    textShadowColor: "#000",
    textShadowRadius: 10,
  },
});

Enter fullscreen mode Exit fullscreen mode

Resultado

Image description

Link do projeto: https://github.com/mensonones/ReactNativeGQL

É isso! Qualquer dúvida, sugestão ou crítica, basta comentar abaixo :)

Latest comments (0)