DEV Community

Emerson Vieira
Emerson Vieira

Posted on

3 3

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 :)

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more