我正在构建消息传递应用程序。我每隔5秒钟使用setTimeout从后端检索一次消息日志,并将其存储在状态变量中。每次超时时,我还将其滚动到聊天窗口的底部,但我试图使其仅在响应对象中有新消息时才发生。问题是我无法在检索它的函数中访问状态变量。理想情况下,我将响应对象的长度与状态变量的当前长度进行比较,以确定是否有新的响应。
这是我的代码:
import React from "react"
import axios from "axios"
export default function Messaging(props) {
const [messages, setMessages] = React.useState([])
const getMessages = () => {
const config = {
method: "get",
url: "localhost:3001/get-messages",
}
axios(config)
.then((response) => {
console.log(messages.length) // prints 0 in reference to the initial state value
if (response.data.get.records.length !== messages.length) {
// function to scroll to the bottom of the chat window
}
setMessages(response.data.get.records)
setTimeout(getMessages, 5000)
})
}
console.log(messages.length) // prints actual value correctly
// Initial retrieval of chat log
React.useEffect(() => {
getMessages()
}, [])
}
在处理逻辑方面,我也乐于接受更好的建议。预先感谢!
答案 0 :(得分:3)
setMessages
将在下一个渲染器中更新messages
考虑到这一点,您可以创建一个效果,只要messages.length
发生更改,它就会滚动到您的元素
import React from "react"
import axios from "axios"
export default function Messaging(props) {
const [messages, setMessages] = React.useState([])
React.useEffect(() => {
// store the id to clear it out if required
let timeoutId
const getMessages = () => {
const config = {
method: "get",
url: "localhost:3001/get-messages",
}
axios(config)
.then((response) => {
// store the messages
setMessages(response.data.get.records)
// here we tell to poll every 5 seconds
timeoutId = setTimeout(getMessages, 5000)
})
}
getMessages()
return () => {
if (timeoutId) {
clearTimeout(timeoutId)
}
}
}, [setMessages])
React.useEffect(() => {
// code here to scroll
// this would only trigger if the length of messages changes
}, [messages.length])
}
我还在您的第一个效果中添加了清理功能,因此当您卸载组件时,请清理timeout
并避免任何额外的请求