在Next TypeScript项目中设置Apollo客户端

3ks5zfa0  于 2023-04-30  发布在  TypeScript
关注(0)|答案(1)|浏览(134)

我已经阅读了关于在React here中设置Apollo客户端的文档。但是,我不知道如何在Next TypeScript项目中设置它。有人能帮我吗?非常感谢。下面是我的项目目录树

.
|   .eslintrc.json
|   .gitignore
|   file.txt
|   next-env.d.ts
|   next.config.js
|   package.json
|   README.md
|   tsconfig.json
|   yarn.lock
+---.next           
+---node_modules
+---public
\---src
    +---graphql               
    |       client.ts
    |       query.ts
    +---pages
    |   |   categories.tsx
    |   |   index.tsx
    |   |   loading.tsx
    |   |   login.tsx
    |   |   profile.tsx
    |   |   _app.tsx
    |   |   _document.tsx
    |   +---api
    |   \---components
    |       +---dashboard
    |       |       NewCourseCard.tsx
    |       |       SuggestedCourses.tsx
    |       |       TopicList.tsx
    |       +---layouts
    |       |   |   layout.tsx
    |       |   \---bar
    |       |           navbar.tsx
    |       |           sidebar-selection.tsx
    |       |           sidebar.tsx
    |       +---profile
    |       |       StudyCourseTable.tsx
    |       |       TeachingCourseTable.tsx
    |       \---widgets
    |               Button.tsx
    |               ContinueLink.tsx
    |               CourseCard.tsx
    |               Logo.tsx
    |               ProgressPercentage.tsx
    +---styles
    \---types
            course.ts
            helper.ts
            user.ts
gfttwv5a

gfttwv5a1#

根据塞尔坎Akman的回答,我做了一个像这样的登录表单:

  • src/graphql/query。ts
import { gql } from "@apollo/client"

export const LOGIN = gql`
  mutation Mutation($email: String!, $password: String!) {
    login(email: $email, password: $password)
  }
`
  • src/graphql/client。ts
import { ApolloClient, InMemoryCache, createHttpLink } from "@apollo/client"

import { setContext } from "@apollo/client/link/context"

const authLink = setContext((_, { headers }) => {
  const token = localStorage.getItem("new-user-token")
  return {
    headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : null,
    },
  }
})

const HttpLink = createHttpLink({
  uri: "http://localhost:4000",
})

const client = new ApolloClient({
  cache: new InMemoryCache(),
  link: authLink.concat(HttpLink),
})

export default client
  • src/pages/login.tsx(我的登录表单)
import { LOGIN } from "@/graphql/query"
import { useMutation } from "@apollo/client"
import { useState } from "react"
// some other imports here 

const LoginPage = ({ setToken }: { setToken: any }) => {
  const [email, setEmail] = useState<string>("")
  const [password, setPassword] = useState<string>("")
  const [loginMutation] = useMutation(LOGIN, {
    variables: { email, password },
    onError: (error) => console.error(error),
    onCompleted: (data) => {
      setToken(data.login)
      localStorage.setItem("new-user-token", data.login)
    },
  })

  const submit = (event: any) => {
    event.preventDefault()
    loginMutation()
    setPassword("")
  }

  return (
     // a login form here
  )
}
  • src/pages/_app.土耳其电信公司
import { ApolloProvider } from "@apollo/client"
import type { AppProps } from "next/app"
import Layout from "./components/layouts/layout"
import client from "@/graphql/client"
// some other imports

export default function App({ Component, pageProps }: AppProps) {
  return (
    <ApolloProvider client={client}>
      <Layout>
        <Component {...pageProps} />
      </Layout>
    </ApolloProvider>
  )
}
  • src/pages/components/layout.tsx:如果没有token,则显示登录表单。
import LoginPage from "@/pages/login"
import Sidebar from "./bar/sidebar"
import { useApolloClient } from "@apollo/client"
import { useState } from "react"

const Layout = ({ children }: { children: React.ReactNode }) => {
  const [token, setToken] = useState<string>("")
  const client = useApolloClient()
  const logout = () => {
    setToken("")
    localStorage.clear()
    client.resetStore()
  }
  if (!token) {
    return (
      <main className={styles.main}>
        <LoginPage setToken={setToken} />
      </main>
    )
  }
  return (
    <main>
      <Sidebar logout={logout} />
      <div>
        <div>{children}</div>
      </div>
    </main>
  )
}

export default Layout

虽然后端运行良好,但前端useMutation()钩子不能正常工作。后端服务器无法接收任何内容以创建令牌。我做错了什么?

相关问题