가로 1, 세로 1 크기의 작은 정사각형으로 이루어진 큰 사각형의 대각선 두 꼭짓점을 선분으로 이었을 때, 선분이 통과하는 작은 정사각형 교차점의 갯수를 구해야 했다. 이때, 바로 큰 사각형의 가로(w), 세로(h) 길이의 최대공약수(gcd(w, h))가 교차점의 갯수이다.
function getGcd (n, m) {
let gcd = 0
let max = Math.max(n ,m)
let min = Math.min(n, m)
while (true) {
// 최대공약수
const quot = Math.floor(max/min)
const remains = max%min
if (remains === 0) {
gcd = min
break
} else {
max = min
min = remains
}
}
return gcd
}
먼저 숫자 몇까지의 소수집합을 구할지 배열공간을 만들어 놓은 후, 2부터 1씩 증가시키며 2배수 이상의 숫자들을 지워준다. 이미 지워진 숫자는 건너 뛴다. 아래는 자바스크립트로 짠 코드
function solution(n) {
let arr = []
// 1은 소수가 아니고, 2부터 소수가 될 수 있으므로, 2부터 구하고자 하는 값까지의 배열을 만든다.
for (let i = 2; i <= n; i++) {
arr[i] = i
}
// 2부터 시작해서 2배수 이상의 숫자를 모두 지우되, 이미 지워진 숫자는 건너 뛴다.
for (let i = 2; i <= n; i++) {
for (let j = i + i; j <= n; j += i) {
if (arr[j] === 0) {
continue
}
arr[j] = 0
}
}
return arr.filter((item) => item !== 0).length
}
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 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를 공식으로 지원하면서 이 방식을 권장할 것 같다...