我正在尝试使用 Next.js 和 Dgraph 构建一个实时聊天应用程序。我找到了一个博客,他们在其中逐步解释了如何使用 React.js 来完成。我认为在 Next.js 上实现它会很容易,但我很难解决一个问题(博客网址 => https://dgraph.io/blog/post/real-time-chat-app- with-react-and-slash-graphql/)。
第一个包.json
{
"name": "realtime-chat-app",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@apollo/client": "^3.0.0-rc.12",
"@apollo/link-ws": "^2.0.0-beta.3",
"@apollo/react-hooks": "^4.0.0",
"graphql": "^15.5.1",
"next": "11.0.1",
"react": "17.0.2",
"react-dom": "17.0.2",
"subscriptions-transport-ws": "^0.9.16"
},
"devDependencies": {
"eslint": "^7.32.0",
"eslint-config-next": "11.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-config-standard": "^16.0.3",
"eslint-plugin-import": "^2.24.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-promise": "^5.1.0",
"eslint-plugin-react": "^7.24.0",
"prettier": "^2.3.2"
}
}
第二个_App.js
我的 _app.js 文件与博客上显示的文件略有不同。我使用“动态组件”来强制客户端渲染
import dynamic from 'next/dynamic'
import { ApolloProvider } from '@apollo/client'
import '../styles/globals.css'
const apolloClient = dynamic(() => import('./../shared/apollo/ApolloSetup'), { ssr: false })
function MyApp ({ Component, pageProps }) {
console.log(apolloClient)
return (
<ApolloProvider client={apolloClient}>
<Component {...pageProps} />
</ApolloProvider>
)
}
export default MyApp
第三次也是最后一次
以下文件与博客上的文件完全相同,但我添加了它们以防万一。
ApolloSetup.js
import { ApolloClient } from '@apollo/client/core'
import { getMainDefinition } from '@apollo/client/utilities'
import { InMemoryCache } from '@apollo/client/cache'
import { HttpLink, split } from '@apollo/client'
import { WebSocketLink } from '@apollo/link-ws'
const endpoint = 'enpoint'
const wsLink = new WebSocketLink({
uri: `wss://${endpoint}`,
options: {
reconnect: true
}
})
const httpLink = new HttpLink({
uri: `https://${endpoint}`
})
const link = split(
// split based on operation type
({ query }) => {
const definition = getMainDefinition(query)
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
)
},
wsLink,
httpLink
)
export default new ApolloClient({
cache: new InMemoryCache(),
link
})
查询.js
import { gql } from '@apollo/client'
const SUBSCRIPTION_QUERY = gql`
subscription {
queryMessage(order: { desc: time }) {
name
text
time
}
}
`
const SEND_MESSAGE = gql`
mutation sendMessage($name: String!, $text: String!, $time: DateTime!) {
addMessage(input: [{ name: $name, text: $text, time: $time }]) {
message {
name
text
time
}
}
}
`
export { SUBSCRIPTION_QUERY, SEND_MESSAGE }
Post.js
import React, { useState } from 'react'
import { useMutation, useSubscription } from '@apollo/client'
import { SUBSCRIPTION_QUERY, SEND_MESSAGE } from './../../shared/apollo/Query'
const Posts = () => {
const [name, setName] = useState('')
const [text, setText] = useState('')
const [sendMessage, { error: mutationError }] = useMutation(SEND_MESSAGE)
const { data, error: subscriptionError } = useSubscription(SUBSCRIPTION_QUERY)
if (!data || !data.queryMessage) return (<h1>Connecting...</h1>)
if (subscriptionError || mutationError) return (<h1>Error...</h1>)
const handleClick = () => {
if (name && text) {
sendMessage({ variables: { name, text, time: (new Date()).toISOString() } })
}
}
return (
<>
<hr></hr>
<label>Enter you name : </label>
<input required type="text" name="name" maxLength="25" onChange={e => setName(e.target.value)}></input>
<label> Enter your message : </label>
<input required type="text" name="message" onChange={e => setText(e.target.value)}></input>
<button type="button" onClick={() => handleClick()}>Post</button>
<hr></hr>
<h3>Total Posts : {data.queryMessage.length}</h3>
<hr></hr>
<table>
<thead>
<tr>
<th>Time</th>
<th>Author</th>
<th>Post</th>
</tr>
</thead>
<tbody>
{data.queryMessage.map((m, index) => (
<tr key={index}>
<td>{(new Date(m.time)).toUTCString()}</td>
<td align="left">{m.name}</td>
<td width="1000" align="left">{m.text}</td>
</tr>
))}
</tbody>
</table>
</>
)
}
export default Posts
运行项目时显示错误
我很确定那是因为 ssr 但我试图在组件上强制 csr 并且我仍然遇到同样的问题。我是使用 apollo 和 websockets 的新手,也许这是一个愚蠢的问题,但我找不到问题所在