리액트 네이티브 개초보로서(일주일차) 처음에는 직접 setState 를 하다가

노마드코더 님의 리액트 훅스 강좌를 보고, Node.js 그래프큐엘 강좌를 보고, 이를 연동하는 React Apollo 강좌를 보고

3연속 충격...

 

이건 꼭 써야한다.

 

리액트에서 그래프큐엘을 사용하는 방식은 2가지가 있다.

알기로는 최근에 공식적으로 리액트 훅스를 지원하게 되면서 기존에 더해서 한가지 방법이 추가된 것.

일단 샘플 프로젝트의 구조는 다음과 같다.

단순히 apolloClient.js 모듈을 App.js 에서 가져와서 적용해주고, 실제 그래프큐엘을 패치할 컴포넌트에서 쿼리를 가져와 사용하는 부분만 보면 된다(아래설명)

 

 

 

1. 필요모듈

*서버단은 이미 그래프큐엘 API로 제작되어있다고 가정

npm install @apollo/react-hooks apollo-boost graphql

기본적인 모듈 외에 위의 모듈을 추가로 설치해야한다.

 

 

 

2. 클라이언트 생성

appolloClient.js

import ApolloClient from "apollo-boost";
import utils from "./commons/utils";

const client = new ApolloClient({
    uri: utils.getApiServer
});

export default client;

위와 같이 apollo-boost 에서 클라이언트를 가져와 uri를 설정하며 생성한다. utils.getApiServer 는 단지 호스트:포트 를 반환하는 커스텀 모듈이다.(직접 주소를 써주면 됨)

 

 

 

3. 클라이언트 주입

App.js

import React from 'react';
import { ApolloProvider } from '@apollo/react-hooks';

// 사용자정의모듈
import client from "./src/apolloClient";
import Router from "./src/route";

export default function App() {
  return (
    <ApolloProvider client={client}>
      <Router />
    </ApolloProvider>
  );
}

App.js 파일에 ApolloProvider 를 가져온다. redux를 설정할 때와 비슷하게 ApolloProvider 태그에 위에서 만들어둔 객체를 client 속성에 주입해준다. Router 는 나의 경우 materialTopTabNavigator 위에 createStackNavigator 를 올려서 구성했다(모르겠으면 구글링 ㄱㄱ)

 

 

 

4. 쿼리예시

queries.js

import { gql } from "apollo-boost";
// import gql from 'graphql-tag';

export const HOME_PAGE = gql`
    query {
        people {
            id
            name
            age
            gender
        }
    }   
`;

예시는 Person 객체의 배열을 가져오는 쿼리다. gql 을 apollo-boost에서 가져오느냐 graphql-tag 에서 가져오느냐는 선택이지만, 최신 공식문서에서는 apollo-boost 에서 가져온다.(예전에는 graphql-tag만 사용했음)

여기서 만들어둔 쿼리를 필요한 컴포넌트에서 import해서 사용하게 된다.

 

 

 

5. 실제 컴포넌트에서의 사용방법 2가지(택1)

 

1) Query 태그 사용방법

Home.js

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Query } from "react-apollo";

// 사용자정의모듈
import utils from "../commons/utils";
import { HOME_PAGE } from "../queries";

/**
 * 피드목록컴포넌트 - Query 태그를 사용하는 방식
 * @method
 */
const Home = () => 
    <Query query={HOME_PAGE}>
        {
            ({loading, data, error}) => {

                console.log("=============");
                console.log(loading);
                console.log(data);
                console.log(error);
                console.log("=============");

                let template = ``;
                if(loading) {template = <Text>`로딩중... ${loading}`</Text>;}
                if(error) {template = <Text>`에러발생 : ${error}`</Text>;}
                if(data && data.people){
                    template = data.people.map((item, index) => 
                        <Text key={index}>{item.id} / {item.name}</Text>
                    )
                }
                return (<View>{template}</View>);
            }
        }
    </Query>
export default Home;

 

2) useQuery 메서드 사용방법

Home2.js

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { useQuery } from '@apollo/react-hooks';

// 사용자정의모듈
import utils from "../commons/utils";
import { HOME_PAGE } from "../queries";

/**
 * 피드목록컴포넌트 - useQuery 메서드를 사용하는 방식
 * @method
 */
const Home = () => {
    const { loading, error, data } = useQuery(HOME_PAGE);

    console.log("=============");
    console.log(loading);
    console.log(data);
    console.log(error);
    console.log("=============");
    
    let template = ``;
    if (loading) {template = <Text>`로딩중... ${loading}`</Text>;}
    if (error) {template = <Text>`에러발생 : ${error}`</Text>;}
    if (data && data.people) {
      template = data.people.map((item, index) => 
        <Text key={index}>{item.id} / {item.name}</Text>
      )
    }
    return (<View>{template}</View>);
}
export default Home;

자... 여기가 중요하다. 이부분 설명하려고 글쓰는것임.

두 컴포넌트는 완벽히 동일하게 작동하지만 문법이 다르다.

위의 방식은 react-apollo 모듈에서 Query 를 가져와 태그형식으로 가져온 데이터를 뷰에 그려준다. query={작성한쿼리} 속성을 주입하고, <Query> 태그 안에 스크립트문을 작성하는데, 이때 함수를 작성해주어야 하며, 이 함수가 반환한 jsx가 결과적으로 랜더린된다! Query 태그 안에서 함수를 작성해야 한다는 방식이 다소 생소하긴 하다.

 

두번째(아래) 방법은 좀더 언어적?인 것 같다. @apollo/react-hooks 에서 useQuery 를 가져와

const { loading, error, data } = useQuery(HOME_PAGE); 형식으로 쿼리를 인자로 넘겨 메서드를 호출한다.

그리고 data 를 가져와 jsx를 만들어 반환해주면 랜더링된다. 좀 더 우리에게 익숙한 방식인듯. 아마 그래서 최신에 react-hooks를 공식으로 지원하면서 이 방식을 권장할 것 같다...

 

결과

'Javascript > React Native' 카테고리의 다른 글

[React Native] android build profile 설정 차이 정리  (0) 2023.12.30
블로그 이미지

망원동똑똑이

프로그래밍 지식을 자유롭게 모아두는 곳입니다.

,