gpt4 book ai didi

reactjs - React 中的 AWS Amplify,如何从订阅的监听器呈现新数据

转载 作者:行者123 更新时间:2023-12-04 07:49:53 30 4
gpt4 key购买 nike

我正在开发一个 React 项目并使用 AWS Amplify 作为无服务器后端的工具,其中我有一个 DynamoDB 作为我在 AWS 云中的数据库。
我的 React 应用程序需要检测 DynamoDB 中的实时数据更新。我正在使用 Amplify 的 GraphQL API。
Amplify 生成的 GraphQL API 提供了一个 subscriptions用于订阅实时数据更改的 API。我认为这正是我需要的,所以我正在使用它:

import React, {useEffect, useState, useRef} from 'react';
import Amplify, { API, graphqlOperation } from 'aws-amplify';
import { onCreateData } from './graphql/subscriptions';

// subscribe to listen to new data creation in DynamoDB
const subscription = API.graphql(
graphqlOperation(onCreateData)
).subscribe({
next: (newData) => {
// New data is received here outside 'App' functional component,
// how can I render the data then?
console.log(`new data: ${JSON.stringify(newData)}`);

}
});

// I can't put the above subscription code inside App component, I don't know why but it just doesn't work unless I move it outside the App functional component.

function App() {
const [dataArray, setDataArray] = useState([]);
...

useEffect(() => {
fetchDataArray();
showDataArray();
return () => {
//cleanup
}
}, [dataArra])

return (<div>
<canvas ref={canvasRef}/>
</div>)
}

export default App;

问题是 subscription对于 DynamoDB 中的新数据插入,仅当我将其放在 function App(){...} 之外时才有效正如你在上面看到的。所以,当 newData在订阅回调中收到 next: (newData) , 如何在 App 中显示新数据成分?
你可以看到我的 App组件我有状态变量 dataArray ,理想的解决方案是更新此 dataArray状态与 newData但我认为现在不可能了。所以,总的来说,我想知道如何在 App 中显示新数据。现在组件?
附言 Amplify GraphQL API doc sample code (如果您看到“订阅”部分)还显示订阅代码与导入处于同一级别。

最佳答案

我们在我们的项目中使用了 amplify,我们有一个例子是下面的一个简单的聊天功能:

interface ChatMessagesProps {
internal?: boolean
convoId: string
}

export const ChatMessages: FC<ChatMessagesProps> = ({ internal, convoId }) => {
const classes = useStyles()
const {
appState: { user }
} = useAppState()

let [messages, setMessages] = useState<any>([])
let [currentConversationId, setConversationId] = useState<string>(convoId)
const listRef = useRef<VariableSizeProps>()

let subscription = useRef<ISubscriptionObject | null>(null)
let updateSubscription = useRef<ISubscriptionObject | null>(null)

const addNewMessage = ({ onCreateMessage }) => {
console.log(onCreateMessage)
// from here we can do whatever we want with the data within the context of this component
}

const messageUpdated = ({ onUpdateMessage }) => {
console.log(onUpdateMessage)
// from here we can do whatever we want with the data within the context of this component
}

const getConversationDetails = async () => {
subscription.current = graphQLSubscription(
onCreateMessage,
{ conversationId: currentConversationId },
addNewMessage
)

updateSubscription.current = graphQLSubscription(
onUpdateMessage,
{ conversationId: currentConversationId },
messageUpdated
)
}

useEffect(() => {
if (currentConversationId) {
getConversationDetails()
}
return () => {
subscription?.current?.unsubscribe()
updateSubscription?.current?.unsubscribe()
}
}, [currentConversationId])

return (
<div className={classes.root}>
<MessageList listRef={listRef} messages={messages} internal={internal} />
<MessageInput userId={user?.id || ''} internal={internal} conversationId={currentConversationId} />
</div>
)
}

const useStyles = makeStyles(() => ({
root: {
width: '100%',
height: '100%',
backgroundColor: 'white',
position: 'relative'
}
}))
我们使用助手 graphQLSubscription
export const graphQLSubscription = (subscription: string, options: any, callback: (d: any) => void) => {
return API.graphql(graphqlOperation(subscription, options)).subscribe({
next: ({ value: { data, errors } }) => {
console.log(errors)
callback(data)
}
})
}
对于您的示例代码,您只想将订阅存储在 ref 中,以便能够在卸载时取消订阅
import React, {useEffect, useState, useRef} from 'react';
import Amplify, { API, graphqlOperation } from 'aws-amplify';
import { onCreateData } from './graphql/subscriptions';

function App() {
const [dataArray, setDataArray] = useState([]);
const subscriptionRef = useRef()
...

useEffect(() => {
fetchDataArray();
showDataArray();

subscriptionRef.current = API.graphql(
graphqlOperation(onCreateData)
).subscribe({
next: (newData) => {
// New data is received here outside 'App' functional component,
// how can I render the data then?
console.log(`new data: ${JSON.stringify(newData)}`);
}
});

return () => {
//cleanup
subscriptionRef.current.unsubscribe()
}
}, [dataArra])

return (<div>
<canvas ref={canvasRef}/>
</div>)
}

export default App;
从那里您可以将其提取到组件内或项目内的辅助函数中,如上

关于reactjs - React 中的 AWS Amplify,如何从订阅的监听器呈现新数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67039064/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com