javascript - 使用套接字 io 时奇怪的反应本机状态行为
问题描述
嗨,目前我正在尝试创建一个简单的群聊应用程序。当我在 useEffect 上使用它时
useEffect(() => {
// i want to fetch data from the backend first and concat it with the msg that will be send during the chat
handleGetGroupMessage();
let socket = io(socketUrl);
socket.on("GroupChat", (msg) => {
console.log("this is the chat messages", chatMessages);
setChatMessages(chatMessages.concat(msg));
});
}, []);
加载应用程序时,来自我后端的所有消息都存储在该状态下。但是当我发送一条新消息时,所有数组都被替换为聊天对象。所以我 console.log 了 chatMessages 状态,它是一个空数组。我想要的是用 msg 对象连接以前的状态
注意:chatMessages 状态是一个对象数组
这是我的全部内容
import React, { useEffect, useState, useContext } from "react";
import {
View,
StyleSheet,
SafeAreaView,
FlatList,
Text,
TouchableHighlight,
Keyboard,
} from "react-native";
import { LinearGradient } from "expo-linear-gradient";
import Constants from "expo-constants";
import colors from "../config/colors";
import { TextInput } from "react-native-gesture-handler";
import { MaterialCommunityIcons } from "@expo/vector-icons";
import { sendMessage, getGroupMessage } from "../api/chatApi";
import io from "socket.io-client";
import AuthContext from "../auth/AuthContext";
import { socketUrl } from "../config/url";
import axios from "axios";
import { apiUrl } from "../config/url";
const GroupChatScreen = (props) => {
const authContext = useContext(AuthContext);
const [chatMessages, setChatMessages] = useState([]);
const [chat, setChat] = useState(null);
const handleSendMessage = async (chat) => {
const result = await sendMessage({ chat }, authContext.token);
setChat(null);
Keyboard.dismiss();
let socket = io(socketUrl);
socket.emit("GroupChat", result);
};
const handleGetGroupMessage = () => {
axios
.get(`${apiUrl}/messages/group`, {
headers: { token: authContext.token },
})
.then((data) => {
setChatMessages(data.data);
})
.catch((error) => {
console.log(error);
});
};
useEffect(() => {
// i want to fetch data from the backend first and concat it with the msg that will be send
console.log(authContext.userData, "userdata");
handleGetGroupMessage();
let socket = io(socketUrl);
socket.on("GroupChat", (msg) => {
console.log("this is the chat messages", chatMessages);
setChatMessages(chatMessages.concat(msg));
});
}, []);
return (
<LinearGradient
colors={[colors.BLUE, colors.DARKBLUE]}
style={styles.container}
>
<View style={styles.chatTitleContainer}>
<Text style={styles.chatTitle}>Pub Chat</Text>
</View>
<FlatList
style={styles.flatList}
keyExtractor={(item) => item.ChatId.toString()}
data={chatMessages}
renderItem={({ item }) => {
if (item.from === authContext.userData.id) {
return (
<View style={styles.fromMe}>
<View style={styles.myChatContainer}>
<Text style={styles.myChat}>{item.chat}</Text>
</View>
</View>
);
} else {
return (
<View style={styles.fromYou}>
<Text style={styles.yourUsername}>{item.username}</Text>
<View style={styles.yourChatContainer}>
<Text style={styles.yourChat}>{item.chat}</Text>
</View>
</View>
);
}
}}
></FlatList>
<View style={styles.textInputContainer}>
<TextInput
onChangeText={(text) => setChat(text)}
style={styles.textInput}
value={chat}
placeholder="Enter Chat Here"
/>
<TouchableHighlight
onPress={() => handleSendMessage(chat)}
style={styles.roundButton}
>
<MaterialCommunityIcons
name="send"
color="white"
size={30}
style={styles.roundButtonIcon}
/>
</TouchableHighlight>
</View>
</LinearGradient>
);
};
export default GroupChatScreen;
const styles = StyleSheet.create({
chatTitle: {
fontSize: 20,
padding: 10,
color: "white",
textAlign: "center",
},
chatTitleContainer: {
backgroundColor: "#031f47",
width: "110%",
height: 40,
justifyContent: "center",
alignContent: "center",
},
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
marginTop: Constants.statusBarHeight,
},
flatList: {
width: "90%",
},
textInput: {
width: "80%",
height: 50,
backgroundColor: "white",
marginRight: 8,
borderRadius: 10,
paddingLeft: 20,
fontSize: 20,
},
textInputContainer: {
width: "100%",
justifyContent: "center",
alignItems: "center",
flexDirection: "row",
marginLeft: 10,
},
roundButton: {
height: 60,
width: 60,
alignContent: "center",
justifyContent: "center",
backgroundColor: "#042048",
borderRadius: 90,
marginRight: 10,
},
roundButtonIcon: {
textAlign: "center",
},
fromMe: {
alignSelf: "flex-end",
},
fromYou: {
alignSelf: "flex-start",
},
myChat: {
textAlign: "left",
fontSize: 18,
color: "white",
},
yourChat: {
textAlign: "right",
fontSize: 18,
color: "white",
},
myChatContainer: {
backgroundColor: colors.MYCHATCOLOR,
paddingRight: 5,
paddingLeft: 15,
paddingTop: 10,
paddingBottom: 10,
borderColor: "white",
borderWidth: 1.5,
borderTopLeftRadius: 15,
borderBottomRightRadius: 15,
borderBottomLeftRadius: 15,
marginTop: 20,
},
yourChatContainer: {
backgroundColor: colors.YOURCHATCOLOR,
paddingRight: 15,
paddingLeft: 9,
paddingTop: 10,
paddingBottom: 10,
borderColor: "white",
borderWidth: 1.5,
borderTopRightRadius: 15,
borderBottomRightRadius: 15,
borderBottomLeftRadius: 15,
},
yourUsername: {
color: "white",
fontSize: 20,
marginBottom: 10,
marginTop: 10,
},
});
when the chatscreen loaded all the messages from backend loaded just fine
when i send a new chat message all the array was replaced with just one message
解决方案
推荐阅读
- java - 如何使用 sbt-assembly 插件设置 build.sbt?
- linux - 在内核模块中创建指向文件的符号链接
- ios - 从 Array 中获取随机唯一元素,直到在 Swift 中选择了所有元素
- mysql - Eloquent 获取关系计数等于列值的行
- android - 导入 android.support.design.widget.FloatingActionButton;
- django - 我的电子邮件链接无法访问正确的路径
- menu - 如何在 VS Code 中将项目添加到“文件菜单”?
- hyperledger-fabric - Hyperledger Composer 文档附件支持
- php - Symfony4 无法在电子邮件中提供路由所需的令牌
- data-warehouse - 由于缺少一个外键而拆分事实表?