Apollo-Setup, react-router-dom

김종민·2022년 9월 15일
0

Nuber-Client

목록 보기
2/21


apollo setup
react-router-dom
코드가 길데 작성되어 있는데, 확인할 부분만 확인하면 됨.

1. Apollo-setup

공식문서
https://www.apollographql.com/docs/react/get-started/

npm install @apollo/client graphql

  1. src/apollo.ts
import {
  ApolloClient,
  InMemoryCache,
  ApolloProvider,
  gql,
  makeVar,
  createHttpLink,
} from '@apollo/client'
import { LOCALSTORAGE_TOKEN } from './constant'
import { setContext } from '@apollo/client/link/context'

const token = localStorage.getItem(LOCALSTORAGE_TOKEN)
export const isLoggedInVar = makeVar(Boolean(token))
export const authTokenVar = makeVar(token)

const httpLink = createHttpLink({
  uri: 'http://localhost:4000/graphql',
  ///backend port를 4000번으로 바꿔줌.
  ///반그시 backend도 실행시켜주어야 함.
})

const authLink = setContext((_, { headers }) => {
  return {
    headers: {
      ...headers,
      'x-jwt': authTokenVar() || '',
    },
  }
})

export const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache({
    typePolicies: {
      Query: {
        fields: {
          isLoggedIn: {
            read() {
              return isLoggedInVar()
            },
          },
          token: {
            read() {
              return authTokenVar
            },
          },
        },
      },
    },
  }),import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import reportWebVitals from './reportWebVitals'
import './styles/styles.css'
import { ApolloProvider } from '@apollo/client'
import { client } from './apollo'

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
root.render(
  <React.StrictMode>
    <ApolloProvider client={client}>
      <App />
    </ApolloProvider>
  </React.StrictMode>
)

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals()

})

2.index.ts

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import reportWebVitals from './reportWebVitals'
import './styles/styles.css'
import { ApolloProvider } from '@apollo/client'
import { client } from './apollo'

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
root.render(
  <React.StrictMode>
    <ApolloProvider client={client}> 
    ////여기에 ApolloProvider로 감싸줌.///
      <App />
    </ApolloProvider>
  </React.StrictMode>
)

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals()

2. react-router-dom

https://v5.reactrouter.com/web/guides/quick-start
npm i react-router-dom

npm i @types/react-router-dom
error가 발생하면 위의 거를 npm i 해본다.

1. src/router/logged-out-router.tsx

import React from 'react'
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'
import { NotFound } from '../pages/404'
import { CreateAccount } from '../pages/create-account'
import { Login } from '../pages/login'

export const LoggedOutRouter = () => {
  return (
    <Router>
      <Routes>
        <Route path="/signup" element={<CreateAccount />} />
        <Route path="/" element={<Login />} />
        <Route path="*" element={<NotFound />} />
      </Routes>
    </Router>
  )
}

2. logged-in-router.tsx

import React from 'react'
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'
import { useMe } from '../hooks/useMe'
import { NotFound } from '../pages/404'
import Category from '../pages/client/category'
import RestaurantDetail from '../pages/client/restaurantDetail'
import Restaurants from '../pages/client/restaurants'
import Search from '../pages/client/search'
import AddDish from '../pages/owner/add-dish'
import AddRestaurant from '../pages/owner/add-restaurant'
import MyRestaurant from '../pages/owner/my-restaurant'
import MyRestaurants from '../pages/owner/my-restaurants'
import ConfirmEmail from '../pages/user/confirm-email'
import EditProfile from '../pages/user/edit-profile'

const clientRoutes = [
  { path: '/', element: <Restaurants /> },
  { path: '/search', element: <Search /> },
  { path: '/category/:slug', element: <Category /> },
  { path: '/restaurants/id', element: <RestaurantDetail /> },
]

const commonRoutes = [
  { path: '/confirm', element: <ConfirmEmail /> },
  { path: '/edit-profile', element: <EditProfile /> },
]

const ownerRoutes = [
  { path: '/', element: <MyRestaurants /> },
  { path: '/add-restaurant', element: <AddRestaurant /> },
  { path: '/restaurants/:id', element: <MyRestaurant /> },
  { path: '/restaurants/:restaurantId/add-dish', element: <AddDish /> },
]

export const LoggedInRouter = () => {
  const { data, loading, error } = useMe()
  console.log(data)
  if (!data || loading || error) {
    return (
      <div className="h-screen flex justify-center items-center">
        <span className="font-medium text-xl tracking-wide">Loading..</span>
      </div>
    )
  }
  return (
    <Router>
      <Routes>
        {data.me.role === 'Client' &&
          clientRoutes.map((route, index) => (
            <Route key={index} path={route.path} element={route.element} />
          ))}
        {data.me.role === 'Owner' &&
          ownerRoutes.map((route, index) => (
            <Route key={index} path={route.path} element={route.element} />
          ))}
        {commonRoutes.map((route, index) => (
          <Route key={index} path={route.path} element={route.element} />
        ))}
        <Route path="*" element={<NotFound />}></Route>
      </Routes>
    </Router>
  )
}

3. src/app.tsx

import { useReactiveVar } from '@apollo/client'
import React from 'react'
import { isLoggedInVar } from './apollo'
import { LoggedInRouter } from './router/logged-in-router'
import { LoggedOutRouter } from './router/logged-out-router'

function App() {
  const isLoggedIn = useReactiveVar(isLoggedInVar)
  return isLoggedIn ? <LoggedInRouter /> : <LoggedOutRouter />
}

export default App

app.tsx에서 어느 router로 보낼지 결정함.!!

router는 어려운 부분이 없으니, 코드만 보면 다 알 수 있음.

profile
코딩하는초딩쌤

0개의 댓글