Next.js: μ΅œμ†Œν•œμ˜ μ•„ν΄λ‘œ 예

에 λ§Œλ“  2016λ…„ 12μ›” 13일  Β·  60μ½”λ©˜νŠΈ  Β·  좜처: vercel/next.js

λ°˜μ‘ μ•„ν΄λ‘œ λŒ€μ‹  μ•„ν΄λ‘œ ν΄λΌμ΄μ–ΈνŠΈλ₯Ό 직접 μ‚¬μš©ν•  λ•Œ 폴둜 톡합이 훨씬 μ‰½λ‹€λŠ” 것이 λ°ν˜€μ‘ŒμŠ΅λ‹ˆλ‹€.

μ½”λ“œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€. https://github.com/nmaro/apollo-next-example
그리고 μ—¬κΈ° μ‹€ν–‰ 쀑인 버전이 μžˆμŠ΅λ‹ˆλ‹€(적어도 graphql μ„œλ²„λ₯Ό 온라인 μƒνƒœλ‘œ μœ μ§€ν•˜λŠ” ν•œ): https://apollo-next-example-oslkzaynhp.now.sh

κ΄€λ ¨ μ„ΈλΆ€ μ •λ³΄λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

μ•„ν΄λ‘œ.js

import ApolloClient, {createNetworkInterface} from 'apollo-client'

export default new ApolloClient({
  networkInterface: createNetworkInterface({
    uri: GRAPHQL_URL
  })
})

그런 λ‹€μŒ νŽ˜μ΄μ§€μ—μ„œ

import React from 'react'
import gql from 'graphql-tag'
import 'isomorphic-fetch'
import apollo from '../apollo'
import Link from 'next/link'

const query = gql`query {
  posts {
    _id
    title
  }
}`
export default class extends React.Component {
  static async getInitialProps({req}) {
    return await apollo.query({
      query,
    })
  }
  render() {
    ...
  }
}

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

Apollo λΈ”λ‘œκ·Έμ—μ„œ Apollo + Next.js에 λŒ€ν•œ λΈ”λ‘œκ·Έ κ²Œμ‹œλ¬Όμ„ 가져와야 ν•©λ‹ˆλ‹€!

λͺ¨λ“  60 λŒ“κΈ€

λͺ‡ 가지 κ΄€μ°° 사항: 이 μ ‘κ·Ό 방식은 λ°œμƒν•˜λŠ” λͺ¨λ“  graphql 쿼리λ₯Ό λ‘œλ“œν•˜κΈ° μœ„ν•΄ ꡬ성 μš”μ†Œμ— 깊이 듀어가지 μ•ŠμŠ΅λ‹ˆλ‹€(λ°˜μ‘ μ•„ν΄λ‘œλ‘œ μ„œλ²„ 츑을 ν™œμ„±ν™”ν•  수 μžˆλŠ” 것).

λ‚˜λŠ” 이것이 next.jsμ—μ„œ μ•½κ°„ λ¬Έμ œκ°€ μžˆλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„ μΈ‘ λͺ¨λ‘μ—μ„œ λ°œμƒν•˜κΈ°λ₯Ό μ›ν•œλ‹€λ©΄ ꡬ성 μš”μ†Œ 계측 κ΅¬μ‘°μ—μ„œ 데이터λ₯Ό κΉŠμˆ™μ΄ λ‘œλ“œν•  μ˜λ„κ°€ μ•„λ‹™λ‹ˆλ‹€. 데이터λ₯Ό λ‘œλ“œν•  지점은 루트 ꡬ성 μš”μ†Œμ˜ getInitialProps에 ν•˜λ‚˜λ§Œ μžˆμŠ΅λ‹ˆλ‹€. 이것이 λ―Έλž˜μ— λ°”λ€”μ§€λŠ” λͺ¨λ₯΄κ² μ§€λ§Œ, 그렇지 μ•Šλ‹€λ©΄ μš°λ¦¬λŠ” ν•΄μ•Ό ν•  κ²ƒμž…λ‹ˆλ‹€.

  1. μ²˜μŒλΆ€ν„° νŽ˜μ΄μ§€μ— λŒ€ν•œ λͺ¨λ“  κ΄€λ ¨ 데이터λ₯Ό λ‘œλ“œν•˜λ„λ‘ 앱을 κ΅¬μ„±ν•˜κ±°λ‚˜
  2. λ‹€λ₯Έ μ „λž΅μ„ μ‚¬μš©ν•˜μ—¬ ν΄λΌμ΄μ–ΈνŠΈμ—λ§Œ μžˆλŠ” λ°μ΄ν„°μ˜ 일뢀(즉, getInitialPropsμ—μ„œ λ‘œλ“œν•˜μ§€ μ•Šμ€ λͺ¨λ“  것)

두 경우 λͺ¨λ‘ μœ„μ˜ μ ‘κ·Ό 방식은 getInitialProps에 λ‘œλ“œλ˜λŠ” 데이터에 적합해야 ν•©λ‹ˆλ‹€.

그리고 일뢀 핡심 κ°œλ°œμžκ°€ 이것을 μ’‹μ•„ν•œλ‹€λ©΄ 예제둜 ν’€ λ¦¬ν€˜μŠ€νŠΈλ₯Ό 생성할 수 μžˆμŠ΅λ‹ˆλ‹€.

λ£¨νŠΈμ—μ„œλ§Œ ν˜ΈμΆœλ˜λŠ” getInitialProps에 λŒ€ν•΄μ„œλŠ” https://github.com/zeit/next.js/issues/192λ₯Ό μ°Έμ‘°ν•˜μ„Έμš”. 거기에 λ‹Ήμ‹ μ˜ 아이디어λ₯Ό κ°–κ³  μ‹ΆμŠ΅λ‹ˆλ‹€.

@sedubois react-apollo 에 μ–΄λ–€ λ¬Έμ œκ°€ μžˆμ—ˆλ‚˜μš”?

@nmaro κ·€ν•˜μ˜ https://github.com/nmaro/apollo-next-example 이 λΉ„μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

@amccloud 에 이에 λŒ€ν•΄ @nmaro μ—κ²Œ λ¬Όμ–΄λ³΄λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€(λ‚˜λŠ” μ—¬μ „νžˆ μ½”λ“œλ‘œ λŒμ•„κ°€μ•Ό ν•©λ‹ˆλ‹€).

@sedubois κ°μ‚¬ν•©λ‹ˆλ‹€. 이제 온라인 μƒνƒœκ°€ λ˜μ—ˆμŠ΅λ‹ˆλ‹€(μ²˜μŒμ—λŠ” push push origin master 을 μ‹€ν–‰ν•˜λŠ” 것을 μžŠμ§€ λ§ˆμ‹­μ‹œμ˜€).

μ•—, μ œκ°€ μ—‰λš±ν•œ μ‚¬λžŒμ„ μ–ΈκΈ‰ν–ˆμŠ΅λ‹ˆλ‹€. @nmaro react-apollo에 μ–΄λ–€ λ¬Έμ œκ°€ μžˆμ—ˆλ‚˜μš”?

데이터가 μ„œλ²„μ— λ‘œλ“œλœ λ‹€μŒ ν΄λΌμ΄μ–ΈνŠΈκ°€ λ‘œλ“œλ₯Ό μ‹œμž‘ν•˜μžλ§ˆμž νŽ˜μ΄μ§€κ°€ λ‹€μ‹œ λΉ„μ–΄ μžˆμ—ˆμŠ΅λ‹ˆλ‹€. 그런 λ‹€μŒ @sedubois 의 κ΅¬ν˜„(https://github.com/RelateMind/relate)을 보고 λΉ λ₯Έ κ°œλ… 증λͺ…을 μœ„ν•΄ 이미 μƒλ‹Ήνžˆ λ³΅μž‘ν•˜λ‹€κ³  μƒκ°ν•˜μ—¬ λ§ˆμΉ¨λ‚΄ ν•˜μœ„ μˆ˜μ€€ API둜 μ‹œλ„ν–ˆμŠ΅λ‹ˆλ‹€.

@stubailo apolloλ₯Ό next.js와 ν†΅ν•©ν•˜λŠ” 것이 μ™œ κ·Έλ ‡κ²Œ μ–΄λ €μš΄μ§€ κΆκΈˆν•˜κΈ° λ•Œλ¬Έμ— - ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„ λͺ¨λ‘μ—μ„œ 데이터λ₯Ό κ°€μ Έμ˜¬ 수 μžˆλŠ” μœ μΌν•œ μž₯μ†ŒλŠ” getInitialPropsλΌλŠ” 비동기 ν•¨μˆ˜ λ‚΄λΆ€μ˜ νŽ˜μ΄μ§€ 루트 ꡬ성 μš”μ†ŒμΈ 것 κ°™μŠ΅λ‹ˆλ‹€. react-apolloλ₯Ό ν†΅ν•©ν•˜λŠ” 일반적인 방법은 ν΄λΌμ΄μ–ΈνŠΈ μΈ‘μ—μ„œλ§Œ μœ μš©ν•  것이라고 μƒκ°ν•©λ‹ˆλ‹€.

ν₯λ―Έλ‘­μŠ΅λ‹ˆλ‹€. Next.js와 λ‹€λ₯Έ 데이터 톡합이 μžˆμŠ΅λ‹ˆκΉŒ? λ‚΄κ°€ λ³Έ 예제λ₯Ό 기반으둜 Reduxλ₯Ό μ‚¬μš©ν•˜λŠ” 것도 κ½€ μ–΄λ €μš΄ 것 κ°™μŠ΅λ‹ˆλ‹€.

λŒ€λΆ€λΆ„μ˜ μ΅œμ‹  데이터 μ‹œμŠ€ν…œμ—λŠ” μΌμ’…μ˜ μ „μ—­ μΊμ‹œ(Redux, Apollo, Relay)κ°€ μžˆμœΌλ―€λ‘œ 이λ₯Ό ν™œμ„±ν™”ν•˜λ €λ©΄ Next에 μΌμ’…μ˜ μ‹œμ„€μ΄ ν•„μš”ν•˜λ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.

κΈ€λ‘œλ²Œ μΊμ‹œ(Redux, Apollo, Relay)κ°€ μžˆλŠ” μ΅œμ‹  데이터 μ‹œμŠ€ν…œμ—μ„œ Next.jsκ°€ 더 잘 μž‘λ™ν•˜λ„λ‘ ν•˜λ €λ©΄ μ–΄λ–»κ²Œ ν•΄μ•Ό ν• κΉŒμš”? 이것이 λ‹€μŒ 릴리슀의 큰 μš°μ„  μˆœμœ„κ°€ λ˜μ–΄μ•Ό ν•œλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. @stubailo @rauchg

μ „μ μœΌλ‘œ. Wiki에 Redux μ˜ˆμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€. 이와 μœ μ‚¬ν•œ 예제λ₯Ό 더 λ§Œλ“€μ–΄μ•Ό ν•©λ‹ˆλ‹€. :)

릴리슀 κΈ°μ€€μœΌλ‘œ ν•΄μ•Ό ν•˜λŠ” 것은 μ•„λ‹™λ‹ˆλ‹€. btw. μš°λ¦¬λŠ” μ–Έμ œλ“ μ§€ μœ„ν‚€ νŠœν† λ¦¬μ–Όμ„ μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Btw @nmaro κ·Έ μ˜ˆμ œλŠ” 정말 깔끔해 λ³΄μž…λ‹ˆλ‹€. κΈ°μ—¬ν•΄ μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€. μš°λ¦¬λŠ” 그것을 기반으둜 μ‚Όκ³  ν™•μž₯ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

였, μ΄μƒν•©λ‹ˆλ‹€. κ΄€λ ¨λœ 문제λ₯Ό 깨닫지 λͺ»ν–ˆμŠ΅λ‹ˆλ‹€. @nmaro 상황을 μ–΄λ ΅κ²Œ λ§Œλ“œλŠ” react-apolloλŠ” λ¬΄μ—‡μž…λ‹ˆκΉŒ? redux 예제λ₯Ό 거의 μ •ν™•ν•˜κ²Œ λ”°λ₯Ό 수 μžˆμ–΄μ•Ό ν•˜μ§€λ§Œ createStore λ₯Ό μ‚¬μš©ν•˜λŠ” new ApolloClient λ₯Ό μˆ˜ν–‰ν•˜κ³  Provider ApolloProvider λ₯Ό μ‚¬μš©ν•  수 μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.

λˆ„κ΅°κ°€μ™€ ν•¨κ»˜ μ΅œμ†Œν•œμ˜ 예λ₯Ό λ§Œλ“€κ³  μ‹ΆμŠ΅λ‹ˆλ‹€. 이것은 React에 λŒ€ν•œ "hello world" μ˜ˆμž…λ‹ˆλ‹€. Next.js에 λŒ€ν•œ ν¬νŠΈκ°€ 있으면 쒋을 κ²ƒμž…λ‹ˆλ‹€. https://github.com/apollostack/frontpage-react-app

@stubailo μ΅œμ†Œν•œμ˜ 예제둜 λ‹Ήμ‹ κ³Ό ν•¨κ»˜ μΌν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€. μ €λŠ” λͺ‡ 가지 ν”„λ‘œμ νŠΈλ₯Ό μœ„ν•΄ λ²”μš© apollo λ§ˆμ΄ν¬λ‘œν”„λ ˆμž„μ›Œν¬μΈ Saturn을 μ‚¬μš©ν•΄ μ™”μœΌλ©° ꢁ극적으둜 이λ₯Ό Next.js + Apollo둜 μ΄μ‹ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€. :)

μ’‹μ•„μš” - 예, create-react-app λŒ€μ‹  next.jsμ—μ„œ μ‹€ν–‰λ˜λ„λ‘ ν”„λ‘ νŠΈνŽ˜μ΄μ§€ 앱을 μ΅œμ†Œν•œμœΌλ‘œ μˆ˜μ •ν•˜λŠ” 것이 제 μ·¨ν–₯μž…λ‹ˆλ‹€. 그러면 저희 ν™ˆνŽ˜μ΄μ§€μ—λ„ 등둝할 수 μžˆμŠ΅λ‹ˆλ‹€!

@μŠ€νˆ¬λ°”μΌλ‘œ

μž‘μ€ λ¬Έμ œλŠ” 데이터가 μ„œλ²„μ—μ„œ λ‘œλ“œ 및 λ Œλ”λ§λ˜μ—ˆμ§€λ§Œ ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ λ‘œλ“œν•  λ•Œ 아무것도 κ΅μ²΄λ˜μ§€ μ•ŠλŠ”λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. apollo-clientλ₯Ό 직접 μ‚¬μš©ν•˜λ©΄ 이 λ¬Έμ œκ°€ λ°œμƒν•˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.

μ„œλ²„ λ Œλ”λ§μ—μ„œ 더 κΉŒλ‹€λ‘œμš΄ 것은 계측 ꡬ쑰에 더 κΉŠμ€ 쿼리가 μžˆλŠ” κ²½μš°μž…λ‹ˆλ‹€. Reactμ—λŠ” λΉ„λ™κΈ°μ‹μœΌλ‘œ λ Œλ”λ§ν•˜λŠ” 방법이 μ—†μŠ΅λ‹ˆλ‹€. 즉, λ Œλ”λ§ν•˜κΈ° 전에 각 ꡬ성 μš”μ†Œκ°€ 쀀비될 λ•ŒκΉŒμ§€ κΈ°λ‹€λ¦½λ‹ˆλ‹€. μ΄λŠ” ssr ν”„λ ˆμž„μ›Œν¬κ°€ λ‹€μŒ 쀑 ν•˜λ‚˜λ₯Ό μˆ˜ν–‰ν•΄μ•Ό 함을 μ˜λ―Έν•©λ‹ˆλ‹€.

  1. 전체 ꡬ성 μš”μ†Œ 트리λ₯Ό 두 번, ν•œ λ²ˆμ€ 데이터λ₯Ό λ‘œλ“œν•˜κ³  ν•œ λ²ˆμ€ λ Œλ”λ§ν•©λ‹ˆλ‹€.
  2. λ£¨νŠΈμ— 비동기 μ§„μž…μ  제곡 - 이것은 getInitialPropsλ₯Ό μ‚¬μš©ν•œ next.js μ ‘κ·Ό λ°©μ‹μž…λ‹ˆλ‹€.

이제 λ¬Έμ œλŠ” apolloκ°€ ꡬ성 μš”μ†Œ 트리λ₯Ό λ Œλ”λ§ν•˜λŠ” 데 ν•„μš”ν•œ λͺ¨λ“  데이터 ν˜ΈμΆœμ„ κ°μ§€ν•˜κ³  getInitialProps에 μ œκ³΅ν•  수 μžˆλŠ” ν•˜λ‚˜μ˜ ν•¨μˆ˜ ν˜ΈμΆœμ—μ„œ 이 λͺ¨λ“  μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 방법이 μžˆλŠ”μ§€ μ—¬λΆ€μž…λ‹ˆλ‹€.

@stubailo 이것에 λŒ€ν•œ 해결책이 μžˆμŠ΅λ‹ˆκΉŒ? ^^

@nmaro @ads1018 getDataFromTree λ³΄μ…¨λ‚˜μš”? λ‚΄ μ˜ˆμ—μ„œ μ‚¬μš©λœ κ²ƒμ²˜λŸΌ: https://github.com/RelateMind/relate/blob/master/hocs/apollo.js

BTW 이제 https://github.com/zeit/next.js/pull/301 이 λ³‘ν•©λ˜μ–΄ 일이 κ°„μ†Œν™”λ  수 μžˆλŠ”μ§€ κΆκΈˆν•©λ‹ˆλ‹€. 아직 그것에 λŒ€ν•΄ μ‘°μ‚¬ν•˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.

@seduboi ν™•μΈν–ˆμŠ΅λ‹ˆλ‹€ κ³΅μœ ν•΄μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€! λ„€, react-apolloλ₯Ό μ‚¬μš©ν•˜λŠ” μ˜ˆμ œλŠ” 방금 Master에 λ³‘ν•©λœ μƒˆλ‘œμš΄ ν”„λ‘œκ·Έλž˜λ° 방식 API(#301)λ₯Ό μ‚¬μš©ν•˜μ—¬ λ‹¨μˆœν™”ν•  수 μžˆλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. λ”°λΌμ„œ λͺ¨λ“  νŽ˜μ΄μ§€ ꡬ성 μš”μ†Œλ₯Ό κ³ μœ ν•œ HOC둜 λž˜ν•‘ν•  ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€. 이에 λŒ€ν•΄ 진전이 있으면 μ•Œλ €μ£Όμ„Έμš”! apollo ν™ˆνŽ˜μ΄μ§€μ—μ„œ next.js 예제λ₯Ό 얻을 수 있으면 μ’‹κ² μŠ΅λ‹ˆλ‹€ :)

NB @ads1018 https://github.com/zeit/next.js/pull/301 은 Programmatic APIκ°€ μ•„λ‹Œ CommonsChunkPlugin으둜 곡톡 μ½”λ“œλ₯Ό μΆ”μΆœν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 예, ν”„λ‘œκ·Έλž˜λ° 방식 API도 λΆ„λͺ…νžˆ 도움이 될 것이며 μΆœμ‹œλ˜κΈ°λ₯Ό κ³ λŒ€ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

μƒˆλ‘œμš΄ 2.0.0-beta.2 λ¦΄λ¦¬μŠ€μ™€ ν•¨κ»˜ react-apolloλ₯Ό μ‚¬μš©ν•˜λŠ” ν–‰μš΄μ„ 얻은 μ‚¬λžŒμ΄ μžˆμŠ΅λ‹ˆκΉŒ?

@sedubois @stubailo 보고 μ‹ΆμœΌμ‹œλ‹€λ©΄ next + react-apollo에 λŒ€ν•œ μ‹œλ„λ₯Ό λ―Έλ€˜μŠ΅λ‹ˆλ‹€. μ—¬κΈ°μ—μ„œ 찾을 수 μžˆμŠ΅λ‹ˆλ‹€: https://github.com/ads1018/frontpage-next-app

λ‚΄κ°€ μ§€κΈˆ μ§λ©΄ν•˜κ³  μžˆλŠ” ν•œ 가지 λ¬Έμ œλŠ” ꡬ성 μš”μ†Œκ°€ μ„œλ²„ 츑이 μ•„λ‹Œ ν΄λΌμ΄μ–ΈνŠΈ μΈ‘μ—μ„œλ§Œ λ Œλ”λ§λœλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. μ•„λ§ˆλ„ server.js λ‚΄μ—μ„œ react-apollo의 getDataFromTree λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•  수 μžˆμ„κΉŒμš”? μ•„λ‹ˆλ©΄ 우리 고유의 <document> 내뢀에 μžˆμŠ΅λ‹ˆκΉŒ? λͺ¨λ“  μ œμ•ˆ/ν’€ λ¦¬ν€˜μŠ€νŠΈλ₯Ό ν™˜μ˜ν•©λ‹ˆλ‹€!

ꢁ극적으둜 이 hello world 예제λ₯Ό Next examples 폴더와 Apollo ν™ˆ νŽ˜μ΄μ§€μ— ν¬ν•¨ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€.

데이터λ₯Ό μ„œλ²„μ—μ„œ λ Œλ”λ§ν•˜κΈ° μœ„ν•œ μœ μΌν•œ μ „μ œ 쑰건은 μž¬μ •μ˜ν•  ν•„μš” 없이 getInitialProps 의 개체둜 λ°˜ν™˜λœλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

μž‘μ•˜λ‹€. @nmaro κ°€ μ§€μ ν–ˆλ“―μ΄ λ°˜μ‘ μ•„ν΄λ‘œμ—μ„œλŠ” 이것이 μ•½κ°„ μ–΄λ ΅λ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.

λ¬Έμ œλŠ” apolloκ°€ ꡬ성 μš”μ†Œ 트리λ₯Ό λ Œλ”λ§ν•˜λŠ” 데 ν•„μš”ν•œ λͺ¨λ“  데이터 ν˜ΈμΆœμ„ κ°μ§€ν•˜κ³  getInitialProps에 μ œκ³΅ν•  수 μžˆλŠ” ν•˜λ‚˜μ˜ ν•¨μˆ˜ ν˜ΈμΆœμ—μ„œ 이 λͺ¨λ“  μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 방법이 μžˆλŠ”μ§€ μ—¬λΆ€μž…λ‹ˆλ‹€.

κ°“μ°¨

@ads1018 쑰금 νŒŒκ³ λ“€λ©΄ μ΅œμƒμœ„ ꡬ성 μš”μ†Œ κ°€ getInitialProps에 λ…ΈμΆœλœ 경우 Apollo λ„μš°λ―Έ λ₯Ό μ‚¬μš©ν•˜μ—¬ λ¬Έμžμ—΄λ‘œ λ Œλ”λ§ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

그러면 _documentλŠ” λ‹€μŒκ³Ό 같을 κ²ƒμž…λ‹ˆλ‹€.

export default class MyDocument extends Document {
  static async getInitialProps ({ app }) {
    const wrapped = React.createElement(ApolloProvider, { client }, app)
    const rendered = await renderToStringWithData(wrapped)
    return { html: rendered, initialState: client.store.getState() }
  }

  render () {

    return (
      <html>
        <Head>
          <title>My page</title>
        </Head>
        <body>
          <ApolloProvider client={client}>
            <Main />
          </ApolloProvider>
          <NextScript />
        </body>
      </html>
    )
  }
}

@rauchg renderPage 외에 app λ₯Ό λ…ΈμΆœν•˜λŠ” κ°„λ‹¨ν•œ 변경인 것 κ°™μ§€λ§Œ μ œκ°€ κ°„κ³Όν•˜λŠ” 것이 μžˆμŠ΅λ‹ˆκΉŒ?

@bs1180 μ•„ λŒ€λ°•. λ‚΄κ°€ 찾던 λ°”λ‘œ κ·Έκ±°μ•Ό. app λ₯Ό λ…ΈμΆœν•˜λŠ” κ°„λ‹¨ν•œ 변경이 λ˜μ—ˆμœΌλ©΄ ν•©λ‹ˆλ‹€. 그것은 μ¦‰μ‹œ Nextλ₯Ό graphql ν΄λΌμ΄μ–ΈνŠΈ μΉœν™”μ  ν”„λ ˆμž„μ›Œν¬λ‘œ λ§Œλ“€ κ²ƒμž…λ‹ˆλ‹€.

@bs1180 renderPage λ°˜ν™˜ 객체 내뢀에 app λ₯Ό λ…ΈμΆœν–ˆμŠ΅λ‹ˆλ‹€. 이것은 당신이 μƒκ°ν•œ 것과 μΌμΉ˜ν•©λ‹ˆκΉŒ?

@ads1018 μ •ν™• ν•˜μ§€ μ•ŠμŒ - κ·€ν•˜μ˜ λ²„μ „μ—μ„œ render κ°€ 계속 호좜되고 μžˆμŠ΅λ‹ˆλ‹€ renderToStringWithData κ°€ μˆ˜λ™μœΌλ‘œ 호좜될 경우 λΆˆν•„μš”ν•œ 쀑볡이 될 κ²ƒμž…λ‹ˆλ‹€.

λ‚˜λŠ” 이것에 λŒ€ν•΄ 더 λ§Žμ€ μž‘μ—…μ„ μˆ˜ν–‰ν–ˆκ³  μ΅œμ’… κ²°κ³ΌλŠ” λ‚΄κ°€ 처음 μƒμƒν–ˆλ˜ κ²ƒλ§ŒνΌ μ˜ˆμ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 주둜 κΈ°λ³Έ 앱이 <Main /> ꡬ성 μš”μ†Œμ˜ μžμ‹μœΌλ‘œ λ Œλ”λ§λ˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€(__next div둜). λͺ¨λ“  μ»¨ν…μŠ€νŠΈκ°€ μœ„μ—μ„œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μœΌλ‘œ μ „λ‹¬λ˜λŠ” 것을 λ°©μ§€ν•©λ‹ˆλ‹€. λ”°λΌμ„œ Apollo μ»¨ν…μŠ€νŠΈλ₯Ό λ‹€μ‹œ μΆ”κ°€ν•˜λ €λ©΄ μ—¬μ „νžˆ HOCκ°€ ν•„μš”ν•©λ‹ˆλ‹€.

@bs1180 μ•Œκ² μŠ΅λ‹ˆλ‹€ . <Main /> λ₯Ό ApolloProvider 의 μžμ‹μœΌλ‘œ λ Œλ”λ§ν•˜μ—¬ μ»¨ν…μŠ€νŠΈλ₯Ό 전달할 수 μžˆμŠ΅λ‹ˆκΉŒ?

무슨 말씀인지 λͺ¨λ₯΄κ² μ§€λ§Œ λ°©ν–₯이 잘λͺ»λœ 것 κ°™μ•„μš”. μ™„λ²½ν•œ SSR은 HOC만으둜 달성할 수 μžˆμŠ΅λ‹ˆλ‹€. μ—¬κΈ°μ—μ„œ μ‹œμž‘μ μœΌλ‘œ 자갈이 κ²°ν•©λœ 버전이 μžˆμŠ΅λ‹ˆλ‹€.

export default (options = {}) => Component => class ApolloHOC extends React.Component {
  static async getInitialProps (ctx) {
    const user = process.browser ? getUserFromLocalStorage() : getUserFromCookie(ctx.req)
    const jwt = process.browser ? null : getJwtFromCookie(ctx.req)

    if (options.secure && !user) {
      return null // skip graphql queries completely if auth will fail
    }

    const client = initClient(jwt)
    const store = initStore(client)

   // This inserts the context so our queries will work properly during the getDataFromTree call,
   //  as well as ensuring that any components which are expecting the url work properly 
    const app = React.createElement(ApolloProvider, { client, store },
      React.createElement(Component, { url: { query: ctx.query }}))

 // this is the most important bit :)
    await getDataFromTree(app)

    const initialState = {[client.reduxRootKey]: {
      data: client.store.getState()[client.reduxRootKey].data
    }}

    return { initialState, user }
  }

  constructor (props) {
    super(props)
    this.client = initClient()
    this.store = initStore(this.client, this.props.initialState)
  }

  render () {
    return (
      <ApolloProvider client={this.client} store={this.store}>
          <Component url={this.props.url} />
      </ApolloProvider>
    ) 
  }
}

initClient 및 initStore λŠ” redux μ˜ˆμ œμ—μ„œ λͺ¨λΈλ§λ˜μ—ˆμŠ΅λ‹ˆλ‹€. λͺ¨λ“  νŽ˜μ΄μ§€λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

import ApolloHOC from '../hoc'
import { graphql } from 'react-apollo'

export default ApolloHOC({ secure: false })(() => <b>Hello world</b>)

μœ μš©ν•˜κΈ°λ₯Ό λ°”λžλ‹ˆλ‹€. 쑰사할 λ‹€λ₯Έ 방법이 μžˆλŠ”μ§€, μ•„λ‹ˆλ©΄ μ œκ°€ κ°„κ³Όν•˜κ³  μžˆλŠ” 뢀뢄이 μžˆλŠ”μ§€ μ•Œκ³  μ‹ΆμŠ΅λ‹ˆλ‹€.

@bs1180 λ©‹μ§€λ„€μš” , κ³΅μœ ν•΄μ£Όμ…”μ„œ 정말 μœ μš©ν•©λ‹ˆλ‹€.

_document.js 내뢀에 graphql 데이터가 μžˆλŠ” νŽ˜μ΄μ§€λ₯Ό λ Œλ”λ§ν•˜κΈ° μœ„ν•΄ ν•  수 μžˆλŠ” λ‹€λ₯Έ 것이 μžˆμŠ΅λ‹ˆκΉŒ? μ²˜μŒμ— μ œμ•ˆν•œ κ²ƒμ²˜λŸΌ HOCλ₯Ό λͺ¨λ‘ μš°νšŒν•  수 μžˆλ‹€λ©΄ 쒋을 κ²ƒμž…λ‹ˆλ‹€.

λ‚˜λŠ” κ·Έλ ‡κ²Œ μƒκ°ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ - λ‚΄κ°€ λ³Ό 수 μžˆλŠ” 바에 λ”°λ₯΄λ©΄ ν΄λΌμ΄μ–ΈνŠΈ μΈ‘ λ Œλ” λŠ” μ‚¬μš©μž μ •μ˜ _document.js μ—μ„œ μ»¨ν…μŠ€νŠΈ(Apollo ν΄λΌμ΄μ–ΈνŠΈ, ν‘œμ€€ Redux μŠ€ν† μ–΄, ν…Œλ§ˆ λ“±)에 μ „λ‹¬λ˜λŠ” λͺ¨λ“  것을 μ œκ±°ν•©λ‹ˆλ‹€. Apollo SSR 둜직의 일뢀λ₯Ό 그곳으둜 이동할 수 μžˆμ§€λ§Œ, μ»¨ν…μŠ€νŠΈμ— ν•„μš”ν•œ 객체λ₯Ό λ‹€μ‹œ μΆ”κ°€ν•˜λ €λ©΄ μΌμ’…μ˜ HOC/래퍼 κ΅¬μ„±μš”μ†Œκ°€ μ—¬μ „νžˆ ν•„μš”ν•©λ‹ˆλ‹€.
next.js 내뢀에 λŒ€ν•œ 더 λ‚˜μ€ 지식을 가진 μ‚¬λžŒμ΄ 더 λ‚˜μ€ 아이디어λ₯Ό κ°€μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€.

μž‘μ—… 예제λ₯Ό 얻을 수 μžˆλ‹€λ©΄ ν™•μΈν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€. λ‚˜λŠ” 아직도 이것을 μž‘λ™μ‹œν‚€κΈ° μœ„ν•΄ μ‹Έμš°κ³  μžˆλ‹€.

React Apollo와 Next의 μ‹€μ œ μ˜ˆμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€ πŸ˜„ πŸš€ λ§Žμ€ 뢄듀이 μœ μš©ν•˜κ²Œ μ‚¬μš©ν•˜μ…¨μœΌλ©΄ ν•©λ‹ˆλ‹€. μ—¬κΈ°μ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€: https://github.com/ads1018/next-apollo-example (λ‚˜λ„ Nowλ₯Ό μ‚¬μš©ν•˜μ—¬ 데λͺ¨λ₯Ό λ°°ν¬ν–ˆμŠ΅λ‹ˆλ‹€.)

λ‚˜λŠ” ApolloProvider 둜 νŽ˜μ΄μ§€λ₯Ό κ°μ‹ΈλŠ” withData() λΌλŠ” λ‚΄ νŽ˜μ΄μ§€ λ‚΄λΆ€μ˜ HOCλ₯Ό μ‚¬μš©ν•˜κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€. λ‚˜λŠ” μ²˜μŒμ— 단일 파일 λ‚΄μ—μ„œ ν•œ 번이 μ•„λ‹ˆλΌ νŽ˜μ΄μ§€λ‹Ή 기반으둜 κ³΅κΈ‰μžλ₯Ό μ‚¬μš©ν•˜μ—¬ ν•΄μ œλ˜μ—ˆμ§€λ§Œ 가독성과 ν™•μž₯μ„± λ©΄μ—μ„œ 더 λ‚«λ‹€λŠ” 정말 λ˜‘λ˜‘ν•œ μ‚¬λžŒλ“€μ— μ˜ν•΄ ν™•μ‹ ν–ˆμŠ΅λ‹ˆλ‹€. λ‚˜λŠ” μ‹€μ œλ‘œ withData(MyComponent) κ°€ κ½€ 보기 μ’‹κ³  λ…μžμ—κ²Œ νŠΉμ • νŽ˜μ΄μ§€κ°€ 데이터λ₯Ό κ°€μ Έμ˜€λŠ” 쒋은 μ»¨ν…μŠ€νŠΈλ₯Ό μ œκ³΅ν•œλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€(말μž₯λ‚œμ΄ μ•„λ‹˜).

μ €λ₯Ό μ˜¬λ°”λ₯Έ λ°©ν–₯으둜 μ•ˆλ‚΄ν•΄ μ£Όμ‹  @bs1180 κ³Ό @rauchg μ—κ²Œ κ°μ‚¬λ“œλ¦½λ‹ˆλ‹€. with-apollo 예제λ₯Ό 리포지토리에 μΆ”κ°€ν•˜λ €λ©΄ μ €μ—κ²Œ μ•Œλ €μ£Όμ‹œλ©΄ pull μš”μ²­μ„ 생성할 수 μžˆμŠ΅λ‹ˆλ‹€.

@ads1018 λ‹˜ κ°μ‚¬ν•©λ‹ˆλ‹€ 😊 제 예제 https://Relate.now.sh 와 λΉ„κ΅ν•˜μ—¬ 이 μ˜ˆμ œλŠ” 깊이 μ€‘μ²©λœ ꡬ성 μš”μ†Œμ—μ„œ Apolloλ₯Ό μ‚¬μš©ν•˜λŠ” 문제λ₯Ό ν•΄κ²°ν•©λ‹ˆκΉŒ(getInitialProps의 μΊμŠ€μΌ€μ΄λ“œ 방지)? μ•„λ§ˆλ„ μ˜ˆμ œλŠ” 이것이 μ£Όμš” λ¬Έμ œμ μ΄λ―€λ‘œ 이λ₯Ό 보여주어야 ν•©λ‹ˆλ‹€. 그리고 이것을 examples 폴더에 μΆ”κ°€ν•˜λ©΄ 맀우 감사할 것이라고 ν™•μ‹ ν•©λ‹ˆλ‹€.

@sedubois #192μ—μ„œ μ–ΈκΈ‰ν•œ 였λ₯˜λ₯Ό μž¬ν˜„ν•  수 μ—†μŠ΅λ‹ˆλ‹€. λ‚˜λŠ” 아무 λ¬Έμ œμ—†μ΄ 쀑첩 ꡬ성 μš”μ†Œ λ‚΄λΆ€μ—μ„œ Apolloλ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. λ‚΄ 예λ₯Ό ν’€κ³  μž¬ν˜„ν•  수 μžˆλ‹€λ©΄ μ•Œλ €μ£Όμ‹œκ² μŠ΅λ‹ˆκΉŒ?

@ads1018λ‹˜ , κ°μ‚¬ν•©λ‹ˆλ‹€. https://github.com/ads1018/next-apollo-example/issues/2 πŸŽ‰μ˜ μˆ˜μ • μ‚¬ν•­μœΌλ‘œ λ¬Έμ œκ°€ ν•΄κ²°λ˜μ—ˆμŠ΅λ‹ˆλ‹€. λ‚΄ μ˜ˆμ œλ„ μ—…λ°μ΄νŠΈν–ˆμŠ΅λ‹ˆλ‹€. https://github.com/RelateNow/relate

μˆ˜κ³ ν–ˆμ–΄μš”, @ads1018 @sedubois! λ‚˜λŠ” 이것과 #192λ₯Ό 따라 λ‹€λ…”κ³  Apollo와 바닐라 Reactλ₯Ό μ‚¬μš©ν•˜μ—¬ ν”„λ¦¬νŽ˜μΉ­/비동기 보기도 쑰사 ν–ˆμŠ΅λ‹ˆλ‹€.

각 νŽ˜μ΄μ§€κ°€ ν‘œμ‹œλ˜κΈ° 전에 getDataFromTree λ₯Ό μ‹€ν–‰ν•  λ•Œ μ„±λŠ₯ 문제λ₯Ό λ°œκ²¬ν–ˆκ±°λ‚˜ μ˜ˆμƒν•©λ‹ˆκΉŒ? 기술적으둜 이 λ©”μ„œλ“œλŠ” 전체 트리λ₯Ό μž¬κ·€μ  으둜 λ Œλ”λ§ν•œ λ‹€μŒ getInitialProps κ°€ λ°˜ν™˜λ˜λ©΄ Reactκ°€ 트리λ₯Ό λ‹€μ‹œ λ Œλ”λ§ν•˜λ―€λ‘œ(μΊμ‹œμ—μ„œ κ°€μ Έμ˜¨ 데이터가 μžˆμŒμ—λ„ λΆˆκ΅¬ν•˜κ³ )

정말 멋진 μ†”λ£¨μ…˜ πŸ‘ 두 번 λ Œλ”λ§ν•˜λŠ” 것이 λͺ¨λ“  ν•˜μœ„ 데이터가 μΊμ‹œλ˜λ„λ‘ ν•˜λŠ” μœ μΌν•œ μ˜΅μ…˜μ΄λΌκ³  μƒκ°ν•©λ‹ˆλ‹€. μ„±λŠ₯에 λŒ€ν•΄ μ–΄λ–»κ²Œ μƒκ°ν•˜μ‹œλŠ”μ§€ κΆκΈˆν•©λ‹ˆλ‹€.

μ•ˆλ…•ν•˜μ„Έμš” @estrattonbailey - μ„±λŠ₯ 문제λ₯Ό λˆˆμΉ˜μ±„μ§€ λͺ»ν–ˆμœΌλ©° μ˜ˆμƒν•˜μ§€λ„ μ•ŠμŠ΅λ‹ˆλ‹€. μ‹€μ œλ‘œ, 그것은 맀우 μ΄‰λ°•ν•©λ‹ˆλ‹€! getDataFromTree 싀행에 κ΄€ν•΄μ„œλŠ”, μš°λ¦¬κ°€ μ„œλ²„μ— μžˆλŠ”μ§€ ν™•μΈν•˜λŠ” 쑰건뢀 μ•ˆμ— ν•΄λ‹Ή λ©”μ†Œλ“œ ν˜ΈμΆœμ„ λž˜ν•‘ν•˜μ—¬ μ‚¬μš©μžκ°€ 앱을 처음 λ‘œλ“œν•  λ•Œλ§Œ 호좜되고 μ΄ν›„μ˜ λͺ¨λ“  경둜 λ³€κ²½μ—μ„œ λ¬΄μ‹œλ©λ‹ˆλ‹€. . μ„±λŠ₯을 ν™•μΈν•˜λ €λ©΄ 데λͺ¨ λ₯Ό 가지고 놀 수 μžˆμŠ΅λ‹ˆλ‹€. ν”Όλ“œλ°±μ΄ 있으면 μ•Œλ €μ£Όμ„Έμš”!

@ads1018 κ·€ν•˜μ˜ μ˜ˆμ— λŒ€ν•œ λͺ‡ 가지 아이디어:

  • 이와 같이 initialState λ₯Ό λ‹¨μˆœν™”ν•˜μ‹­μ‹œμ˜€.
  • λ‹€μŒκ³Ό 같은 νŒŒμΌμ— 미듀웨어, μ €μž₯μ†Œ 및 감속기λ₯Ό 뢄리 ν•˜μ‹­μ‹œμ˜€.
  • isServerλ₯Ό typeof window !== 'undefined' 둜 λ‹¨μˆœν™”ν•˜κ³  !!ctx.reqλ₯Ό μ‚­μ œν•©λ‹ˆλ‹€.
  • IS_SERVER constλ₯Ό lib둜 μΆ”μΆœν•˜κ³  param으둜 전달할 ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€.

@ad1018 λ°˜κ°‘ μŠ΅λ‹ˆλ‹€! 쒋은 μž‘μ€ 데λͺ¨.

λ‚΄κ°€ 묻고 싢은 것은 이 규λͺ¨κ°€ μ–Όλ§ˆλ‚˜ λ κΉŒμš”? 아직 Nextλ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šμ•˜μ§€λ§Œ μ΄ν•΄ν•˜λŠ” ν•œ NextλŠ” νŽ˜μ΄μ§€ ꡬ성 μš”μ†Œ(예: pages/page.js )μ—μ„œ μ‚¬μš©ν•  수 μžˆλŠ” 경우 각 경둜 μ „ν™˜μ—μ„œ getInitialProps λ₯Ό ν˜ΈμΆœν•©λ‹ˆλ‹€. 수백 개의 λ…Έλ“œμ™€ λ§Žμ€ 데이터가 λ“€μ–΄μ˜€λŠ” 전체 규λͺ¨μ˜ μ•±/μ›Ήμ‚¬μ΄νŠΈμ—μ„œ 각 κ²½λ‘œμ—μ„œ 두 번 λ Œλ”λ§ν•˜λ©΄ μ•½κ°„μ˜ λŒ€κΈ° μ‹œκ°„μ΄ λ°œμƒν•  수 μžˆλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.

λ‚΄κ°€ μž‘μ—…ν•˜κ³  μžˆλŠ” ν”„λ‘œμ νŠΈλŠ” λŒ€κ·œλͺ¨ νŽΈμ§‘ μ‚¬μ΄νŠΈμ΄λ―€λ‘œ κ·€ν•˜λ₯Ό ν¬ν•¨ν•˜μ—¬ λ‹€μ–‘ν•œ μ ‘κ·Ό 방식을 λ²€μΉ˜λ§ˆν‚Ήν•  수 있기λ₯Ό λ°”λžλ‹ˆλ‹€. μ›ν•œλ‹€λ©΄ νŠΈμœ„ν„° μ—μ„œ 더 λ§Žμ€ λ…Όμ˜λ₯Ό ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€. μž‘μ—…ν•΄μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€!

@estrattonbailey κ°“μ°¨ . λ‚˜λŠ” 그것이 μ•„μ£Ό 잘 ν™•μž₯될 것이라고 μƒμƒν•œλ‹€. 초기 νŽ˜μ΄μ§€ λ‘œλ“œμ˜ 경우 getInitialProps λŠ” μ„œλ²„μ—μ„œλ§Œ μ‹€ν–‰λ©λ‹ˆλ‹€. getInitialProps κ°€ ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ λ‹€μ‹œ μ‹€ν–‰λ˜μ§€λ§Œ getDataFromTree κ°€ μš°λ¦¬κ°€ μ„œλ²„μ— μžˆλŠ”μ§€ μ—¬λΆ€λ₯Ό ν™•μΈν•˜λŠ” 쑰건뢀 μ•ˆμ— λž˜ν•‘λ˜κΈ° λ•Œλ¬Έμ— 데이터가 두 번 μš”μ²­λ˜μ§€ μ•ŠλŠ”λ‹€λŠ” 것은 λ§žμŠ΅λ‹ˆλ‹€.

μ°Έκ³  사항 - νŽ˜μ΄μ§€μ—μ„œ μš”μ²­λ˜λŠ” λ§Žμ€ ꡬ성 μš”μ†Œμ™€ λ°μ΄ν„°λ‘œ 인해 초기 νŽ˜μ΄μ§€ λ‘œλ“œ μ‹œκ°„μ΄ κ±±μ •λ˜λŠ” 경우 항상 apolloμ—κ²Œ SSR λ™μ•ˆ μ˜λ„μ μœΌλ‘œ νŠΉμ • 쿼리λ₯Ό κ±΄λ„ˆλ›°κ³  ssr: false λ₯Ό μ „λ‹¬ν•˜μ—¬ ν΄λΌμ΄μ–ΈνŠΈμ— μ˜€ν”„λ‘œλ“œν•˜λ„λ‘ μ§€μ‹œν•  수 μžˆμŠ΅λ‹ˆλ‹€.

더 μžμ„Έν•œ λ…Όμ˜λ₯Ό μ›ν•˜μ‹œλ©΄ νŠΈμœ„ν„° 둜 연락 λ“œλ¦¬κ² μŠ΅λ‹ˆλ‹€ :)

getInitialPropsκ°€ ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ λ‹€μ‹œ μ‹€ν–‰λ˜μ§€λ§Œ getDataFromTreeκ°€ μš°λ¦¬κ°€ μ„œλ²„μ— μžˆλŠ”μ§€ μ—¬λΆ€λ₯Ό ν™•μΈν•˜λŠ” 쑰건뢀 μ•ˆμ— λž˜ν•‘λ˜κΈ° λ•Œλ¬Έμ— 데이터가 두 번 μš”μ²­λ˜μ§€ μ•ŠλŠ”λ‹€λŠ” 것은 λ§žμŠ΅λ‹ˆλ‹€.

getInitialProps λŠ” 초기 λ‘œλ“œ 이후가 μ•„λ‹ˆλΌ <Link> 둜 μ „ν™˜ν•  λ•Œλ§Œ ν΄λΌμ΄μ–ΈνŠΈ μΈ‘μ—μ„œ μ‹€ν–‰λœλ‹€λŠ” 점을 λͺ…심해야 ν•©λ‹ˆλ‹€.

@ads1018 @estrattonbailey AFAIK 첫 νŽ˜μ΄μ§€ λ‘œλ“œ μ‹œ μ„œλ²„ μΈ‘ λ Œλ”λ§μ΄ 2개 μžˆμŠ΅λ‹ˆλ‹€. getDataFromTreeκ°€ μ‹€ν–‰λ˜κ³  λ‚΄λΆ€μ μœΌλ‘œ 전체 트리λ₯Ό λ Œλ”λ§ν•œ λ‹€μŒ HTML 응닡을 κ΅¬μ„±ν•˜κΈ° μœ„ν•΄ λ Œλ”λ§μ΄ λ‹€μ‹œ ν˜ΈμΆœλ©λ‹ˆλ‹€. 그것을 ν”Όν•  방법이 μžˆλŠ”μ§€ μƒκ°ν•˜μ§€ λ§ˆμ‹­μ‹œμ˜€. κ·ΈλŸ¬λ‚˜ SSR이 ν”Όν•˜λŠ” λ„€νŠΈμ›Œν¬ 왕볡 덕뢄에 μ—¬μ „νžˆ μ„±λŠ₯이 쒋은 것 κ°™μŠ΅λ‹ˆλ‹€.

GraphQL μ„œλ²„κ°€ Next.js μ„œλ²„μ™€ λ™μΌν•œ μ‹œμŠ€ν…œμ—μ„œ ν˜ΈμŠ€νŒ…λ  λ•Œ μ„±λŠ₯이 μ΅œλŒ€μΈ 것 κ°™μœΌλ―€λ‘œ μ„±λŠ₯에 관심이 μžˆλ‹€λ©΄ 항상 μ‹œλ„ν•΄ λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€. λ°±μ—”λ“œ, Next.jsλŠ” Now/Zeit World와 ν•¨κ»˜ 배포됨).

@sedubois @estrattonbailey λ‚΄κ°€ ν‹€λ Έλ‹€λ©΄ μ •μ •ν•΄ μ£Όμ§€λ§Œ μš°λ¦¬λŠ” μ—¬μ „νžˆ ν•œ 번만 λ Œλ”λ§ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. getDataFromTree λŠ” 트리λ₯Ό λ Œλ”λ§ν•˜μ§€ μ•Šκ³  데이터가 Apollo ν΄λΌμ΄μ–ΈνŠΈ μ €μž₯μ†Œμ— μ€€λΉ„λ˜λ©΄ ν•΄κ²°λ˜λŠ” 약속을 λ°˜ν™˜ν•©λ‹ˆλ‹€. 약속이 ν•΄κ²°λ˜λŠ” μ‹œμ μ—μ„œ Apollo ν΄λΌμ΄μ–ΈνŠΈ μ €μž₯μ†Œκ°€ μ™„μ „νžˆ μ΄ˆκΈ°ν™”λ˜κ³  HTTP μš”μ²­μ˜ μ‘λ‹΅μœΌλ‘œ λ¬Έμžμ—΄ν™”λœ κ²°κ³Όλ₯Ό μ „λ‹¬ν•˜λ €λŠ” 경우 선택적 으둜 트리λ₯Ό λ Œλ”λ§ν•  수 μžˆμ§€λ§Œ 제 μ˜ˆμ œμ—μ„œλŠ” κ·Έλ ‡κ²Œ ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

getDataFromTreeλŠ” 트리λ₯Ό λ Œλ”λ§ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

@ads1018 AFAIK 및 Apollo μ½”λ“œ λ₯Ό 보면 트리λ₯Ό μž¬κ·€μ μœΌλ‘œ λ Œλ”λ§ _ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€_ (Apollo 데이터 κ°€μ Έμ˜€κΈ°λ₯Ό νŠΈλ¦¬κ±°ν•˜κΈ° μœ„ν•΄). λ”°λΌμ„œ 첫 νŽ˜μ΄μ§€ λ‘œλ“œ μ‹œ μ„œλ²„ μΈ‘ 2κ°€ λ Œλ”λ§λ©λ‹ˆλ‹€.

ν•˜μ§€λ§Œ μ–΄μ¨Œλ“ , λ‹Ήμ‹ μ˜ 데λͺ¨ 덕뢄에 이제 Apollo와 Next 사이에 μ‚¬μš©ν•  수 μžˆλŠ” 톡합이 생겼고 Apollo SSR μ„±λŠ₯에 λŒ€ν•œ λ‚˜λ¨Έμ§€ μ§ˆλ¬Έμ€ 더 이상 Next.js와 관련이 μ—†λ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. 거기에 λŒ€ν•΄ μ§ˆλ¬Έν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.

@sedubois λ Œλ”κ°€ λ¬΄μ—‡μž…λ‹ˆκΉŒ? λ‚˜λŠ” κ±ΈμœΌλ©΄μ„œ λ‚˜λ¬΄λ₯Ό ν”λ“œλŠ” 것을 λΆ€λ₯΄κ³  μ‹ΆμŠ΅λ‹ˆλ‹€. setState κ°€ μ–΅μ œλ˜κ³  DOM에 λŒ€ν•œ 쑰정이 μ—†μ–΄ μƒλ‹Ήνžˆ μ΅œμ ν™”λœ 것 κ°™μŠ΅λ‹ˆλ‹€.

@ads1018 쒋은 예! μ—¬κΈ° Wiki에도 μΆ”κ°€λœ 것 κ°™μœΌλ‹ˆ 이 문제λ₯Ό 닫을 수 μžˆμ„κΉŒμš”?

cc @rauchg

Apollo λΈ”λ‘œκ·Έμ—μ„œ Apollo + Next.js에 λŒ€ν•œ λΈ”λ‘œκ·Έ κ²Œμ‹œλ¬Όμ„ 가져와야 ν•©λ‹ˆλ‹€!

@stubailo @ads1018 의 μ˜ˆλŠ” ν›Œλ₯­ν•©λ‹ˆλ‹€ πŸ‘ λ™μΌν•œ Apollo 원칙을 μ‚¬μš©ν•˜μ—¬ 더 큰 것을 μœ„ν•΄ λ‚΄ 앱을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€: https://github.com/relatenow/relate

@helperλ‹˜ κ°μ‚¬ν•©λ‹ˆλ‹€. λ‚˜λŠ” 그것이 μ–΄λ–»κ²Œ λ‚˜μ™”λŠ”μ§€μ— λŒ€ν•΄ ν₯λΆ„ν•œλ‹€. Next.js + Apollo둜 μ•± 개발의 μ„±λ°°λ₯Ό λ°œκ²¬ν•œ 것 κ°™μŠ΅λ‹ˆλ‹€. λ‚˜λŠ” λ³΅μŒμ„ μ „νŒŒν•˜κΈ° μœ„ν•œ λ…Έλ ₯의 μΌν™˜μœΌλ‘œ λΈ”λ‘œκ·Έ 포슀트둜 후속 쑰치λ₯Ό μ·¨ν•˜λ €κ³  ν–ˆμ§€λ§Œ, 단지 그것에 λŒ€ν•΄ 닀루지 λͺ»ν–ˆμŠ΅λ‹ˆλ‹€. @stubailo Apollo 맀체 간행물에 λŒ€ν•œ μž‘μ—…μ— ν˜‘λ ₯ν•˜κ²Œ λ˜μ–΄ κΈ°μ©λ‹ˆλ‹€. :)

μ˜ˆμ œμ™€ 그의 멋진 앱을 도와쀀 @sedubois μ—κ²Œ 큰 λ°•μˆ˜λ₯Ό λ³΄λƒ…λ‹ˆλ‹€. πŸ˜„

@ads1018 이 λΈ”λ‘œκ·Έμ— μ—¬λŸ¬λΆ„μ„ μ΄ˆλŒ€ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€. 그것에 λŒ€ν•΄ 이야기할 μ€€λΉ„κ°€ 되면 Apollo Slackμ—μ„œ μ €(thea)μ—κ²Œ 핑을 λ³΄λ‚΄μ£Όμ„Έμš”. :)

@helper 당신이 μ™„μ „νžˆ μ˜³μ•˜μŠ΅λ‹ˆλ‹€. λ¬Έμ œκ°€ μ’…λ£Œλ  수 μžˆλŠ”μ§€ ν™•μΈν•˜λ €λ©΄ μƒˆ 문제λ₯Ό 톡과해야 ν•©λ‹ˆλ‹€. πŸ˜„

@stubailo @theadactyl 멋진 아이디어 ❀️

μ„œλ²„ μΈ‘μ—μ„œ 데이터λ₯Ό 두 번 μš”μ²­ν•˜λŠ” 것과 κ΄€λ ¨ν•˜μ—¬ λ³Ό 문제/PR에 λŒ€ν•΄ μ•„λŠ” μ‚¬λžŒμ΄ μžˆμŠ΅λ‹ˆκΉŒ? κ·Έλƒ₯ κΆκΈˆν•˜λ‹€

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰