在第一次获取数据时做出反应,当用户移动到与另一个用户聊天时,状态值没有改变
In react on first time data is getting fetched, when user move to chat with one another user, state value is not getting change
我是 React 和 Node 的新手,正在尝试构建聊天应用程序,点击用户进行一对一聊天时,我正在从数据库和后端 node.js 获取记录,我也使用过 socket.io.
Chat.js
import React, { useEffect, useRef, useState } from "react"
import io from "socket.io-client"
import { Container,Row,Col,Button} from 'react-bootstrap'
import {useHistory} from 'react-router-dom'
import {fetchUserById,fetchRoom,fetchChats} from '../services/services'
export default function Chat() {
const history=useHistory()
const [username,senderId] =
[localStorage.getItem("username"),localStorage.getItem("senderId")];
const receiverId=window.location.pathname.substr(6)
localStorage.setItem("receiverId",receiverId)
const socketRef = useRef();
const [ oldChat, setOldChat ] = useState([]);
const [receiver, setReceiver] = useState("");
useEffect(()=>{
fetchUserById(receiverId).then(res=> setReceiver(res.data.message[0].username))
})
const receiverUser=receiver
const setLogout=()=>{
localStorage.setItem("loggedin", false);
history.push('/signin');
}
const [ state, setState ] = useState({ senderId:senderId ,message: "", username: username,receiverId:receiverId,roomId:"",receiverUser:receiverUser})
const roomId1=senderId.substr(12);
const roomId2=receiverId.substr(12);
useEffect(
() => {
fetchRoom(roomId1,roomId2).then(res=> {
localStorage.setItem("roomId",res.data.message);
setState({senderId,message:"",username,receiverId,roomId:res.data.message,receiverUser})
})
const roomId=localStorage.getItem("roomId")
fetchChats(roomId,senderId,receiverId).then(res=>{
if(res.data.status===200){
setOldChat([res.data.message])
// console.log(oldChat)
} else{
console.log(res.data.message)
}
})
socketRef.current = io.connect("http://localhost:4000" ,{transports: ['polling']})
socketRef.current.on("message", ({senderId,username, message,receiverId,roomId,receiverUser }) => {
setOldChat([ ...oldChat, { senderId,username, message,receiverId,roomId,receiverUser } ])
})
return () => socketRef.current.disconnect()
},[oldChat]
)
const onTextChange = (e) => {
setState({ ...state, [e.target.name]: e.target.value })
}
const onMessageSubmit = (e) => {
const { senderId, message,receiverId,roomId,receiverUser } = state
if(message===""){
e.preventDefault()
alert("please enter message")
}else{
// console.log("state====>>>",state);
socketRef.current.emit("message", {
senderId,username,message,receiverId,roomId, receiverUser
})
e.preventDefault()
}
}
const renderChat = () => {
return oldChat.map((e)=>{
return e.map((ee)=>{
if(ee.senderId===senderId){
return <div key={ee._id}><b>{username}</b>:{ee.message}</div>
}
else{
return <div key={ee._id}><b>{receiverUser}</b>:{ee.message}</div>
}
})
})
}
return (
<div>
<Container fluid>
<Row className="p-2">
<Col>
<h1 align="left">Login successful</h1>
</Col>
<Col md={{span:2,offset:4}}>
<Button onClick={setLogout} className="btn btn-danger btn-block">Logout</Button>
</Col>
</Row>
<Row className="p-2">
<form onSubmit={onMessageSubmit} style={{float:"right",position:"fixed",right:"150px"}}>
<h1>Send message</h1>
<div>
<input type ="text" name="senderId" disabled value={state.senderId} label="SenderId" />
</div>
<div>
<input type ="text" name="username" disabled value={state.username} label="Username" />
</div>
<div>
<input type ="text" name="roomId" disabled value={state.roomId} label="RoomId" />
</div>
<div>
<input type ="text"
name="message"
onChange={(e) => onTextChange(e)}
value={state.message}
id="outlined-multiline-static"
variant="outlined"
label="Message"
/>
</div>
<button>Send Message</button>
</form>
<div>
<h1 style={{position:"fixed",background:"#fff", marginTop:"0px"}}>Chat log history</h1>enter code here
<p style={{marginTop:"35px"}}> {username} is talking to {receiverUser}</p>
<div style={{float:"left"}}>
{renderChat()}
</div>
</div>
</Row>
</Container>
</div>
)
}
我检查过数据是从后端节点服务器获取的,react.js 有问题。
第一次它会获取聊天记录,但是当我移动到与其他用户聊天时,它会给出上次用户聊天消息,我必须刷新页面,才能获取当前用户的所有聊天消息。
为 fetchChat 使用另一个 useEffect 挂钩 API
useEffect(()=>{
fetchUserById(receiverId).then(res=>
setReceiver(res.data.message[0].username))
},[receiverId])
useEffect(() => {
fetchChats(roomId,senderId,receiverId).then(res=>{
if(res.data.status===200){
setOldChat([res.data.message])
// console.log(oldChat)
} else{
console.log(res.data.message)
}
})
}, [roomId, senderId, receiverId]);
useEffect( () => {
socketRef.current = io.connect("http://localhost:4000" ,{transports:
['polling']})
socketRef.current.on("message", ({senderId,username,
message,receiverId,roomId,receiverUser }) => {
setOldChat([ ...oldChat, { senderId,username,
message,receiverId,roomId,receiverUser } ])
})
return () => socketRef.current.disconnect()
},[oldChat])
我是 React 和 Node 的新手,正在尝试构建聊天应用程序,点击用户进行一对一聊天时,我正在从数据库和后端 node.js 获取记录,我也使用过 socket.io.
Chat.js
import React, { useEffect, useRef, useState } from "react"
import io from "socket.io-client"
import { Container,Row,Col,Button} from 'react-bootstrap'
import {useHistory} from 'react-router-dom'
import {fetchUserById,fetchRoom,fetchChats} from '../services/services'
export default function Chat() {
const history=useHistory()
const [username,senderId] =
[localStorage.getItem("username"),localStorage.getItem("senderId")];
const receiverId=window.location.pathname.substr(6)
localStorage.setItem("receiverId",receiverId)
const socketRef = useRef();
const [ oldChat, setOldChat ] = useState([]);
const [receiver, setReceiver] = useState("");
useEffect(()=>{
fetchUserById(receiverId).then(res=> setReceiver(res.data.message[0].username))
})
const receiverUser=receiver
const setLogout=()=>{
localStorage.setItem("loggedin", false);
history.push('/signin');
}
const [ state, setState ] = useState({ senderId:senderId ,message: "", username: username,receiverId:receiverId,roomId:"",receiverUser:receiverUser})
const roomId1=senderId.substr(12);
const roomId2=receiverId.substr(12);
useEffect(
() => {
fetchRoom(roomId1,roomId2).then(res=> {
localStorage.setItem("roomId",res.data.message);
setState({senderId,message:"",username,receiverId,roomId:res.data.message,receiverUser})
})
const roomId=localStorage.getItem("roomId")
fetchChats(roomId,senderId,receiverId).then(res=>{
if(res.data.status===200){
setOldChat([res.data.message])
// console.log(oldChat)
} else{
console.log(res.data.message)
}
})
socketRef.current = io.connect("http://localhost:4000" ,{transports: ['polling']})
socketRef.current.on("message", ({senderId,username, message,receiverId,roomId,receiverUser }) => {
setOldChat([ ...oldChat, { senderId,username, message,receiverId,roomId,receiverUser } ])
})
return () => socketRef.current.disconnect()
},[oldChat]
)
const onTextChange = (e) => {
setState({ ...state, [e.target.name]: e.target.value })
}
const onMessageSubmit = (e) => {
const { senderId, message,receiverId,roomId,receiverUser } = state
if(message===""){
e.preventDefault()
alert("please enter message")
}else{
// console.log("state====>>>",state);
socketRef.current.emit("message", {
senderId,username,message,receiverId,roomId, receiverUser
})
e.preventDefault()
}
}
const renderChat = () => {
return oldChat.map((e)=>{
return e.map((ee)=>{
if(ee.senderId===senderId){
return <div key={ee._id}><b>{username}</b>:{ee.message}</div>
}
else{
return <div key={ee._id}><b>{receiverUser}</b>:{ee.message}</div>
}
})
})
}
return (
<div>
<Container fluid>
<Row className="p-2">
<Col>
<h1 align="left">Login successful</h1>
</Col>
<Col md={{span:2,offset:4}}>
<Button onClick={setLogout} className="btn btn-danger btn-block">Logout</Button>
</Col>
</Row>
<Row className="p-2">
<form onSubmit={onMessageSubmit} style={{float:"right",position:"fixed",right:"150px"}}>
<h1>Send message</h1>
<div>
<input type ="text" name="senderId" disabled value={state.senderId} label="SenderId" />
</div>
<div>
<input type ="text" name="username" disabled value={state.username} label="Username" />
</div>
<div>
<input type ="text" name="roomId" disabled value={state.roomId} label="RoomId" />
</div>
<div>
<input type ="text"
name="message"
onChange={(e) => onTextChange(e)}
value={state.message}
id="outlined-multiline-static"
variant="outlined"
label="Message"
/>
</div>
<button>Send Message</button>
</form>
<div>
<h1 style={{position:"fixed",background:"#fff", marginTop:"0px"}}>Chat log history</h1>enter code here
<p style={{marginTop:"35px"}}> {username} is talking to {receiverUser}</p>
<div style={{float:"left"}}>
{renderChat()}
</div>
</div>
</Row>
</Container>
</div>
)
}
我检查过数据是从后端节点服务器获取的,react.js 有问题。 第一次它会获取聊天记录,但是当我移动到与其他用户聊天时,它会给出上次用户聊天消息,我必须刷新页面,才能获取当前用户的所有聊天消息。
为 fetchChat 使用另一个 useEffect 挂钩 API
useEffect(()=>{
fetchUserById(receiverId).then(res=>
setReceiver(res.data.message[0].username))
},[receiverId])
useEffect(() => {
fetchChats(roomId,senderId,receiverId).then(res=>{
if(res.data.status===200){
setOldChat([res.data.message])
// console.log(oldChat)
} else{
console.log(res.data.message)
}
})
}, [roomId, senderId, receiverId]);
useEffect( () => {
socketRef.current = io.connect("http://localhost:4000" ,{transports:
['polling']})
socketRef.current.on("message", ({senderId,username,
message,receiverId,roomId,receiverUser }) => {
setOldChat([ ...oldChat, { senderId,username,
message,receiverId,roomId,receiverUser } ])
})
return () => socketRef.current.disconnect()
},[oldChat])