gpt4 book ai didi

javascript - 为什么要执行前一个屏幕组件中的 socket.on() ?

转载 作者:行者123 更新时间:2023-12-01 00:45:03 25 4
gpt4 key购买 nike

我有两个 react 组件。第一个Lobby使用react-native-navigation将Gameroom推送到堆栈。它将套接字对象和其他数据等 Prop 传递给 Gameroom 组件

当在 Gameroom 内按下导航栏的后退按钮时,会发出一个 socket.io leave 事件,并且我已经验证服务器能够听到该事件,因此通过 props 传递的套接字有效。然后,服务器将 left 事件发送回 socket.io room(Gameroom 组件)。

如果将 left 事件监听器放置在 Gameroom 的 componentDidMount() 内部,则不会执行。但是,如果将相同的 socket.io 事件监听器放置在 Lobby 组件(上一屏幕)componentDidMount() 中,则会听到该事件

我尝试将事件监听器添加到多个 componentDidMount 函数,我还考虑过使用 Context API,但我不使用嵌套组件。我正在将react-native-navigation的{passProps}中的套接字对象从一个屏幕传递到另一个屏幕

Lobby:

imports ...
const socket = io("http://192.xxx.xxx.xx:3000");
export default class Lobby extends React.Component {
static options(passProps) {
return {
topBar: {
background: {
color: "transparent"
},
drawBehind: true,
visible: true,
animate: true,
leftButtons: [
{
id: "leave",
icon: require("../assets/img/Chevron.png")
}
]
}
};
}
constructor(props) {
super(props);
this.state = {
username: "Initializing...",
queue: []
};
}
componentDidMount() {
Navigation.events().bindComponent(this);
socket.emit("lobbyEntry");
socket.on("lobbyEntry", entry => {
this.setState({ queue: entry.lobby, username: socket.id });
});
socket.on("userJoined", lobby => {
this.setState({ queue: lobby });
});
// socket.on("left", () => {
// alert("Opponent Left...Oh well");
// Navigation.pop(this.props.componentId);
// });
}
navigationButtonPressed({ buttonId }) {
switch (buttonId) {
case "leave":
socket.emit("leave");
Navigation.popToRoot(this.props.componentId);
break;
}
}
createMatch = () => {
if (this.state.username != "Initializing...") {
socket.emit("findMatch");
socket.on("alreadyCreated", () => {
alert("You already created a match!");
});
socket.on("listUsers", lobby => {
this.setState({ queue: lobby });
});
socket.on("matchFound", data => {
Navigation.push(this.props.componentId, {
component: {
name: "Gameroom",
passProps: {
room: data.id,
socket: socket,
firstMove: data.firstMove,
p1: data.p1,
p2: data.p2
}
}
});
});
} else {
alert("Wait for Username to be initialized...");
}
};
render() {
const bg = getBackground();
return (
<ImageBackground source={bg} style={{ height: "100%", width: "100%" }}>
<View style={styles.title_container}>
<Text style={styles.title_sm}>Matchmaking Lobby</Text>
</View>
<View style={styles.alt_text_container}>
<Text style={styles.alt_text_md}>Username:</Text>
<Text style={styles.alt_text_md}>{this.state.username}</Text>
</View>
<View
style={{
flexDirection: "column",
justifyContent: "center",
alignItems: "center"
}}
>
<XplatformButton onPress={this.createMatch} text={"Create a Match"} />
</View>
<View style={styles.alt_text_container}>
<Text style={styles.alt_text_sm}>Players actively searching...</Text>
<FlatList
style={styles.alt_text_container}
data={this.state.queue}
renderItem={({ item, index }) => (
<Text style={styles.alt_text_md} key={index}>
{item}
</Text>
)}
/>
</View>
</ImageBackground>
);
}
}

游戏室:

import ...
export default class Gameroom extends React.Component {
static options(passProps) {
return {
topBar: {
title: {
fontFamily: "BungeeInline-Regular",
fontSize: styles.$navbarFont,
text: "Gameroom - " + passProps.room,
color: "#333"
},
background: {
color: "transparent"
},
drawBehind: true,
visible: true,
animate: true,
leftButtons: [
{
id: "leave",
icon: require("../assets/img/Chevron.png")
}
]
}
};
}
constructor(props) {
super(props);
Navigation.events().bindComponent(this);
}

navigationButtonPressed({ buttonId }) {
switch (buttonId) {
case "leave":
this.props.socket.emit("leave");
Navigation.pop(this.props.componentId);
break;
}
}

componentDidMount() {
// socket.on("left", () => {
// alert("Opponent Left...Oh well");
// Navigation.pop(this.props.componentId);
// });
}

render() {
const bg = getBackground();
return this.props.p2 != null ? (
<Gameboard
room={this.props.room}
you={
this.props.socket.id == this.props.p1.username
? this.props.p1.marker
: this.props.p2.marker
}
opponent={
this.props.socket.id != this.props.p1.username
? this.props.p2.marker
: this.props.p1.marker
}
move={this.props.firstMove}
socket={this.props.socket}
/>
) : (
<ImageBackground style={styles.container} source={bg}>
<View style={{ marginTop: 75 }}>
<Text style={styles.alt_text_md}>
Waiting for Opponent to Join...
</Text>
</View>
</ImageBackground>
);
}
}

我希望事件监听器从当前屏幕的 componentDidMount() 函数执行,但仅当它位于前一个屏幕的 componentDidMount() 内部时才会执行

最佳答案

当您创建组件时,

the constructor -> componentWillMount -> render -> componentDidMount is followed.

在您的 Lobby 类中,事件监听器会运行,因为它位于 ComponentDidmont 中。

但是,Gameroom 类的事件监听器位于构造函数 内部。如果在构造函数内执行,则无法听到该事件,因为它尚未渲染

事件监听器在屏幕上出现时被调用

使用

  componentDidMount() {
this.navigationEventListener = Navigation.events().bindComponent(this);
}

componentWillUnmount() {
// Not mandatory
if (this.navigationEventListener) {
this.navigationEventListener.remove();
}
}

关于javascript - 为什么要执行前一个屏幕组件中的 socket.on() ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57454125/

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