본문 바로가기

React 실습/Nextjs 실습

[Next.js] 4장 - 코드 구성과 데이터 불러오기

728x90

 (학습 중 메모 정리 - 나중에 할것)

 

USER
getaddrinfo ENOTFOUND api.rwnjs.com?



ChatGPT
"getaddrinfo ENOTFOUND api.rwnjs.com" 에러 메시지는 일반적으로 DNS(Domain Name System)에 의해 도메인 이름 "api.rwnjs.com"을 IP 주소로 변환할 수 없다는 것을 나타냅니다. 이는 네트워크 연결 문제, 올바르지 않은 DNS 서버 구성 또는 도메인 이름 자체의 문제로 인한 것일 수 있습니다.

이 문제를 해결하기 위해 다음과 같은 단계를 시도해 볼 수 있습니다:

인터넷 연결을 확인하고 안정적인 연결을 보장합니다.

DNS 서버가 올바르게 구성되어 있는지 확인합니다.




User
Request URL: http://localhost:3000/
이렇게 되잇는데
  const userReq = await axios.get(` https://api.rwnjs.com/04/users/$ {username}`);
나는 이렇게 요청했는데 요청 url이 다른거야?

 


ChatGPT
네, 요청 URL이 다릅니다.

http://localhost:3000/은 로컬 컴퓨터에서 실행 중인 서버를 가리키는 URL입니다. 즉, localhost는 현재 사용자가 접속한 컴퓨터를 가리킵니다.

반면에, https://api.rwnjs.com/04/users/$ {username}는 "api.rwnjs.com" 도메인을 가진 원격 서버의 URL입니다. 따라서 이 요청은 "api.rwnjs.com"에서 호스팅되는 서버로 보내지며, 이 서버는 ${username}에 해당하는 사용자 데이터를 반환할 것으로 예상됩니다.

따라서, 당신이 요청한 URL과 http://localhost:3000/는 서로 다르며 서로 다른 서버에서 실행중인 것으로 보입니다.




User
아니 같다고
ChatGPT
제가 이해한 바로는, http://localhost:3000/와 https://api.rwnjs.com/04/users/$ {username} 두 URL이 서로 다르다는 것입니다.

http://localhost:3000/는 로컬 컴퓨터에서 실행중인 서버의 URL이고, https://api.rwnjs.com/04/users/$ {username}는 "api.rwnjs.com" 도메인을 가진 외부 서버의 URL입니다. 따라서 이 두 URL은 서로 다른 서버를 가리키고 있습니다.

하지만, 만약 http://localhost:3000/ 서버에서 https://api.rwnjs.com/04/users/$ {username}를 호출하고 있다면, 이 경우 http://localhost:3000/ 서버에서 https://api.rwnjs.com/04/users/$ {username}로 요청이 전송될 것입니다. 이 경우, http://localhost:3000/와 https://api.rwnjs.com/04/users/$ {username}는 다른 URL이지만, http://localhost:3000/ 서버에서 https://api.rwnjs.com/04/users/$ {username}를 호출하는 것이므로 이 두 URL은 함께 사용되고 있는 것입니다.



User
어 맞는데 내가 axios 요청을 했는데 왜 브라우저 검사에서는 내 로컬에다가 요청되냐고 묻는게 요지고 그 원인이 뭐가 될거 같음?
ChatGPT
브라우저 검사에서는 보통 네트워크 탭(Network tab)을 사용하여 네트워크 요청과 응답에 대한 정보를 확인할 수 있습니다. 이 탭에서는 모든 네트워크 활동을 모니터링할 수 있으므로, 로컬 서버에서 외부 서버로의 요청도 포함하여 모든 네트워크 요청을 보여줍니다.

따라서, 당신이 axios를 사용하여 https://api.rwnjs.com/04/users/$ {username}로 요청을 보냈다면, 이 요청은 실제로 https://api.rwnjs.com/04/users/$ {username} 서버로 전송됩니다. 하지만, 이 요청에 대한 응답이 로컬 서버로 반환된다면, 브라우저 검사의 네트워크 탭에서 이 요청이 로컬 서버에서 처리된 것으로 나타날 수 있습니다.

따라서, 이 경우에는 https://api.rwnjs.com/04/users/$ {username} 서버에서 요청을 처리하고 응답을 반환하고, 이 응답이 로컬 서버로 전달되어 브라우저 검사에서 이렇게 보이는 것입니다.



User
ssrMode: typeof window === "undefined", 무슨 의미?

 


ChatGPT
이 코드는 React 애플리케이션에서 서버 사이드 렌더링(Server-Side Rendering, SSR)을 지원하는 라이브러리 중 하나인 styled-components에서 사용되는 코드입니다.

ssrMode는 styled-components에서 제공하는 옵션 중 하나로, 현재 코드가 서버 사이드에서 실행 중인지 클라이언트 사이드에서 실행 중인지를 판별합니다. 이 값이 true이면, 코드가 서버에서 실행 중인 것이며, false이면 코드가 클라이언트에서 실행 중인 것입니다.

위 코드에서 ssrMode 값은 typeof window === "undefined" 표현식을 통해 결정됩니다. 이 표현식은 window 객체가 undefined인지를 확인하여, 현재 코드가 브라우저에서 실행 중인지 아니면 Node.js와 같은 JavaScript 런타임 환경에서 실행 중인지를 판별합니다. window 객체는 브라우저에서만 존재하는 객체이므로, typeof window === "undefined"는 서버 측 코드에서 실행될 때 true가 됩니다.

따라서, 위 코드에서 ssrMode 값이 true가 되면, styled-components는 서버 측에서 렌더링될 때에는 스타일 코드를 다르게 처리하게 됩니다. 서버 측에서 렌더링될 때에는 스타일 코드를 문자열로 변환하여 HTML에 직접 포함시키는 방식으로 처리하기 때문입니다. 이를 통해 SSR을 지원할 수 있습니다.



User
폴리필?

 


ChatGPT
폴리필(polyfill)은 자바스크립트에서 지원하지 않는 기능을 구현하는 코드를 말합니다. 이러한 기능은 보통 최신 브라우저에서는 지원되지만, 오래된 브라우저에서는 지원되지 않을 수 있습니다. 폴리필은 이러한 오래된 브라우저에서도 지원되도록 하기 위해 사용됩니다.

폴리필은 대개 JavaScript 라이브러리로 제공되며, 이 라이브러리를 코드에 포함시키면 지원하지 않는 기능을 구현하는 코드가 자동으로 삽입됩니다. 예를 들어, ES6에서 추가된 Promise 객체는 오래된 브라우저에서는 지원되지 않지만, Promise 객체를 지원하는 폴리필 라이브러리를 사용하면 오래된 브라우저에서도 Promise 객체를 사용할 수 있습니다.

폴리필은 브라우저의 호환성을 유지하기 위해 매우 중요한 역할을 합니다. 최신 브라우저에서는 대부분의 기능이 지원되지만, 오래된 브라우저에서는 지원되지 않는 경우가 많기 때문입니다. 따라서, 모든 사용자가 애플리케이션을 원활하게 사용할 수 있도록 폴리필을 사용하여 브라우저 호환성을 유지하는 것이 좋습니다.


User
isomorphic-unfetch?

 


ChatGPT
isomorphic-unfetch는 웹 브라우저와 Node.js에서 모두 사용할 수 있는 fetch API의 클라이언트 라이브러리입니다. fetch API는 네트워크 요청을 생성하고 응답을 처리하는 방법을 제공하는 JavaScript API이며, 브라우저에서는 기본적으로 제공되지만, Node.js에서는 제공되지 않기 때문에, isomorphic-unfetch를 사용하여 Node.js에서도 fetch API를 사용할 수 있습니다.

isomorphic-unfetch는 서버 측 JavaScript 애플리케이션에서 사용하기 적합한 라이브러리입니다. 예를 들어, Next.js와 같은 프레임워크에서 서버 사이드 렌더링을 할 때, isomorphic-unfetch를 사용하여 서버 측에서도 fetch API를 사용할 수 있습니다.

isomorphic-unfetch는 window.fetch 대신 require('isomorphic-unfetch')를 사용하여 fetch를 불러옵니다. 이를 통해 브라우저와 Node.js에서 모두 fetch API를 사용할 수 있습니다. isomorphic-unfetch는 다양한 브라우저와 Node.js 버전에서 테스트되어 안정적으로 작동하며, 많은 개발자들이 사용하고 있는 라이브러리 중 하나입니다.



User
export function initApollo(initialState = null) {
  const client = apolloClient || createApolloClient();

  if (initialState) {
    const existingCache = client.extract();
    client.cache.restore({ ...existingCache, ...initialState });
  }

  if (typeof window === "undefined") {
    return client;
  }

  if (!apolloClient) {
    apolloClient = client;
  }

  return client;
}

설명좀

 


ChatGPT
위 코드는 Apollo Client를 초기화하는 함수인 initApollo입니다. 이 함수는 initialState 매개변수를 받으며, 이를 사용하여 Apollo Client의 초기 상태를 설정합니다.

먼저, 함수 내부에서 apolloClient 상수가 선언됩니다. 이 변수는 Apollo Client 인스턴스를 저장하기 위한 변수입니다. 만약 apolloClient가 이미 선언되어 있다면, 해당 인스턴스를 사용하고, 그렇지 않으면 createApolloClient() 함수를 호출하여 새로운 인스턴스를 만듭니다.

그 다음, initialState가 null이 아닌 경우, existingCache 변수에 현재 Apollo Client 캐시의 상태를 복사합니다. 그리고 client.cache.restore()를 호출하여 캐시 상태를 초기화합니다. 이렇게 함으로써, 클라이언트에서 서버로부터 데이터를 미리 가져오는 서버 사이드 렌더링에서, 서버와 클라이언트 간의 초기 데이터 전달이 가능합니다.

다음으로, window 객체의 존재 여부를 확인하여, 서버와 클라이언트에서 함수를 호출하는 방식을 나눕니다. 서버 측에서는 client를 반환하며, 클라이언트 측에서는 apolloClient를 저장하고 반환합니다. 이렇게 함으로써, Apollo Client 인스턴스를 다른 파일에서 재사용할 수 있습니다.

이 함수는 Next.js와 같은 SSR 프레임워크에서 Apollo Client를 사용할 때 유용합니다. 이를 통해, 서버 측과 클라이언트 측에서 동일한 Apollo Client 인스턴스를 사용할 수 있으며, 이를 통해 초기 데이터 전달 및 캐시 공유가 가능합니다.



User
import Head from "next/head";
import { ApolloProvider } from "@apollo/client";
import { useApollo } from "../lib/apollo";

export default function App({ Component, pageProps }) {
  const apolloClient = useApollo(pageProps.initialApolloState || {});

  return (
    <ApolloProvider client={apolloClient}>
      <Head>
        <link
          href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css"
          rel="stylesheet"
        />
      </Head>
      <Component {...pageProps} />
    </ApolloProvider>
  );
}
설명 ㄱ


ChatGPT
위 코드는 Next.js에서 사용하는 공통 컴포넌트인 App 컴포넌트입니다. 이 컴포넌트는 모든 페이지에서 공통으로 사용되며, 각 페이지 컴포넌트를 렌더링합니다.

useApollo 함수는 Apollo Client 인스턴스를 초기화하고 반환하는 함수입니다. pageProps.initialApolloState가 존재한다면 해당 상태를 사용하여 Apollo Client를 초기화합니다. initialApolloState는 서버 측 렌더링 시 생성된 초기 데이터 상태를 의미합니다. 초기 데이터 상태는 서버 측에서 데이터를 불러와 클라이언트로 전달하고, 클라이언트는 해당 데이터를 사용하여 Apollo Client 인스턴스를 초기화합니다.

ApolloProvider는 React 컴포넌트이며, 이 컴포넌트를 사용하여 모든 하위 컴포넌트에서 Apollo Client를 사용할 수 있도록 합니다. client prop을 사용하여, 위에서 초기화한 Apollo Client 인스턴스를 전달합니다.

Head 컴포넌트는 Next.js에서 제공하는 기능으로, HTML head 요소를 수정할 수 있는 컴포넌트입니다. 이 컴포넌트를 사용하여, 해당 애플리케이션에서 사용하는 CSS 라이브러리인 Tailwind CSS의 CSS 파일을 로드하도록 합니다.

마지막으로, Component prop과 pageProps prop을 전달하여, 각 페이지 컴포넌트를 렌더링합니다. Component는 Next.js에서 각 페이지를 의미하는 React 컴포넌트를 의미하며, pageProps는 해당 페이지의 초기 데이터 상태를 포함합니다.


User
import { gql } from '@apollo/client';

const GET_LATEST_SIGNS = gql`
  query GetLatestSigns($limit: Int! = 10, $skip: Int! = 0) {
    sign(offset: $skip, limit: $limit, order_by: { created_at: desc }) {
      uuid
      created_at
      content
      nickname
      country
    }
  }
`;

export default GET_LATEST_SIGNS;

설명 ㄱ

 


ChatGPT
위 코드는 Apollo Client에서 사용할 GraphQL 쿼리를 정의하는 코드입니다.

gql 함수는 GraphQL 쿼리를 파싱하기 위해 사용되는 함수입니다. 이 함수는 GraphQL Query Language를 사용하여 쿼리를 정의할 수 있도록 해줍니다.

GET_LATEST_SIGNS 상수는 GraphQL 쿼리 문자열을 담고 있습니다. 이 쿼리는 sign이라는 객체에서 uuid, created_at, content, nickname, country 값을 가져오는 것을 정의합니다. 또한, offset, limit, order_by 등의 변수도 정의됩니다.

이 쿼리는 GetLatestSigns라는 이름의 GraphQL 쿼리로 정의되며, limit과 skip 변수를 매개변수로 받습니다. limit과 skip 변수는 쿼리 실행 시 전달되는 인자로 사용되며, 각각 최대 가져올 레코드 수와 가져올 레코드의 시작 지점을 지정합니다.

이 쿼리는 나중에 Apollo Client에서 사용됩니다. Apollo Client는 이 쿼리를 서버에 보내고, 결과를 받아오는 역할을 수행합니다.


User
limit?


ChatGPT
limit은 데이터베이스에서 가져올 데이터의 최대 개수를 나타내는 매개변수입니다.

예를 들어, 데이터베이스에서 10개의 데이터만 가져오고 싶은 경우, limit 매개변수에 10을 전달하면 됩니다. limit 매개변수를 사용하여 데이터베이스에서 가져올 데이터의 개수를 제한함으로써, 불필요한 리소스 낭비를 줄일 수 있습니다.

GraphQL에서도 limit 매개변수를 사용하여 데이터베이스에서 가져올 데이터의 최대 개수를 지정할 수 있습니다. 이를 이용해, 서버와 클라이언트 간의 데이터 전송량을 최적화하고, 적절한 성능을 유지할 수 있습니다.


User
offset?


ChatGPT
offset은 데이터베이스에서 가져올 데이터의 시작 위치를 나타내는 매개변수입니다.

예를 들어, offset 값이 5인 경우, 데이터베이스에서 5번째 데이터부터 가져오게 됩니다. 이를 이용해, 페이지네이션 등의 기능을 구현할 수 있습니다.

GraphQL에서도 offset 매개변수를 사용하여 데이터베이스에서 가져올 데이터의 시작 위치를 지정할 수 있습니다. 이를 이용해, 서버와 클라이언트 간의 데이터 전송량을 최적화하고, 적절한 성능을 유지할 수 있습니다.





User
Int! ?


ChatGPT
Int!는 GraphQL에서 사용되는 스칼라 타입 중 하나인 Int 타입에 Non-nullable 속성을 추가한 것입니다.

즉, Int!는 반드시 정수값을 가져야하며, null 값을 가질 수 없습니다. 이는 GraphQL에서 타입 시스템을 사용하여 API의 입력과 출력을 정확하게 지정하고 검증할 수 있도록 도와줍니다.

예를 들어, 다음과 같은 GraphQL 스키마가 있다고 가정해보겠습니다.

sql
type Query {
  user(id: Int!): User!
}
위의 스키마에서 id 필드는 반드시 Int 타입의 값이어야 하며, null 값을 가질 수 없습니다. 이는 클라이언트 측에서 API를 호출할 때 id 필드에 잘못된 값이나 null을 전달할 수 없도록 보장해줍니다.





User
$limit 에서 $ 왜 붙는거?


ChatGPT
$는 GraphQL에서 변수를 나타내는 문법적인 요소 중 하나입니다.

$limit은 GraphQL에서 사용되는 변수 이름으로, 쿼리에 변수를 전달하기 위해 사용됩니다. 이를 Query Variables 또는 Input Variables라고 합니다.

Query Variables을 사용하면, 쿼리에 직접 값을 포함시키는 것이 아니라 변수 이름을 사용하여 쿼리 외부에서 값을 전달할 수 있습니다. 이를 통해 쿼리의 재사용성을 높이고, 입력 값의 유효성 검사를 수행하는 등의 기능을 구현할 수 있습니다.

위에서 보여준 쿼리에서 $limit은 GetLatestSigns 쿼리에 전달되는 변수 중 하나입니다. 이를 통해 클라이언트는 limit 매개변수의 값을 원하는 값으로 동적으로 변경할 수 있습니다. 예를 들어, limit 값을 20으로 변경하면, 최신 20개의 글만 가져올 수 있습니다.





User
- error ../node_modules/@apollo/client/react/context/ApolloConsumer.js:2:0
Module not found: Can't resolve 'react' ?


ChatGPT
이 오류는 @apollo/client 패키지에서 react 패키지를 찾을 수 없기 때문에 발생하는 것입니다. 이는 react 패키지가 프로젝트에 설치되어 있지 않기 때문입니다.

해결 방법으로는 react 패키지를 설치하는 것입니다. 다음과 같이 명령어를 입력하여 react 패키지를 설치할 수 있습니다.

npm install react
또는, package.json 파일에서 dependencies 항목에 "react": "^버전"을 추가한 뒤, npm install 명령어를 실행하여 설치할 수도 있습니다.





User
grahql api 에서 restapi 처럼 api 호출을 하는 코드를 보여줘


ChatGPT
GraphQL API에서는 REST API와 달리 각각의 엔드포인트가 아니라 단일 엔드포인트에서 쿼리(Query)와 뮤테이션(Mutation)을 사용하여 데이터를 요청합니다. 이를 위해 클라이언트에서는 graphql이나 @apollo/client 등의 라이브러리를 사용하여 쿼리나 뮤테이션을 전송합니다.

예를 들어, graphql 라이브러리를 사용하여 간단한 쿼리를 전송하는 코드는 다음과 같습니다.

js
Copy code
import { graphql } from 'graphql';
import { schema } from './schema';

const query = `
  {
    user(id: 1) {
      id
      name
      email
    }
  }
`;

graphql(schema, query).then(result => {
  console.log(result.data.user);
});
위 코드는 schema에 정의된 user 타입에 대해 id가 1인 사용자의 id, name, email 필드를 가져오는 쿼리를 전송합니다. graphql 함수는 첫 번째 인자로 schema를, 두 번째 인자로 쿼리를 받습니다. 그리고 반환된 Promise 객체의 data 속성에 쿼리 결과를 포함합니다.

물론, 이는 간단한 예시일 뿐이며, GraphQL에서는 @argument, @directive, @fragment 등의 문법을 사용하여 더 복잡한 쿼리를 작성할 수 있습니다. 또한, @apollo/client 라이브러리를 사용하면 좀 더 간편하게 쿼리를 작성하고 캐싱할 수 있습니다.





User
@apollo/client 사용하는 방법으로 알려줘


ChatGPT
@apollo/client를 사용하여 GraphQL API를 호출하는 방법은 다음과 같습니다.

먼저, 필요한 모듈을 import 합니다.
javascript

import { ApolloClient, InMemoryCache, gql } from '@apollo/client';
ApolloClient 객체를 생성합니다. 이때, GraphQL API의 endpoint URL을 설정합니다.
javascript
Copy code
const client = new ApolloClient({
  uri: ' https://example.com/graphql',
  cache: new InMemoryCache()
});
GraphQL 쿼리를 작성합니다. 예를 들어, users 필드를 가지고 있는 Query 객체를 다음과 같이 정의할 수 있습니다.
javascript
Copy code
const GET_USERS = gql`
  query {
    users {
      id
      name
    }
  }
`;
ApolloClient 객체를 사용하여 GraphQL 쿼리를 실행합니다.
javascript
Copy code
client.query({
  query: GET_USERS
})
.then(result => console.log(result));
결과는 Promise 객체로 반환되며, .then 메소드를 사용하여 처리할 수 있습니다. 예를 들어, 위 예제에서는 콘솔에 쿼리 결과를 출력하도록 설정되어 있습니다.
이렇게 @apollo/client를 사용하여 GraphQL API를 호출할 수 있습니다. 더 자세한 내용은 공식 문서를 참고하시기 바랍니다.




728x90

'React 실습 > Nextjs 실습' 카테고리의 다른 글

[Next.js] SSR, ISR 그리고 Link, Image  (0) 2023.07.04
[Next.js] Next.js 랜더링 방법 - SSG  (0) 2023.07.03