node.js - 如何在 React 中显示组件并在每次显示时更新其生命周期?
问题描述
我刚启动 node.js 并做出反应,我很好奇如何使用 socket.io 创建一个聊天应用程序,所以我遵循了一些关于如何创建房间、加入/离开和在房间中发送消息的教程。我使用 React Context 来传递一个套接字实例。
我可以创建房间,加入它们,离开它们。我遇到的问题是,当我加入另一个房间并尝试发送消息时,我收到以下警告:
无法对未安装的组件执行 React 状态更新。渲染组件时。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,请取消 componentWillUnmount 方法中的所有订阅和异步任务。
你能给我一些关于我应该如何重新考虑为这种情况重写 ReactcomponentDidMount
和componentWillUnmount
函数的建议吗?
我想添加这些详细信息以了解我想要做什么: - 用户可以在其中创建房间的主页 - 房间生成为 2 个按钮,1 个用于显示聊天室(加入房间),另一个用于关闭聊天室(离开房间) - 用户可以加入聊天室并发送消息
客户端(Home.js)
class Home extends Component {
constructor(props) {
super(props);
this.state = {
room: "",
rooms: [],
chat: false
};
this.creatingRoom = this.creatingRoom.bind(this);
this.joinRoom = this.joinRoom.bind(this);
this.leaveRoom = this.leaveRoom.bind(this);
this.props.socket.on("createRoom", function(room) {
addRoom(room);
});
const addRoom = room => {
this.setState({ rooms: [...this.state.rooms, room] });
};
};
creatingRoom(e) {
e.preventDefault();
this.props.socket.emit("creatingRoom", {
room: this.state.room
});
this.setState({ room: "" });
};
joinRoom(e) {
let room = e.target.value;
this.props.socket.emit("joinRoom", room);
this.setState({
chat: true
});
};
leaveRoom(e) {
let room = e.target.value;
this.props.socket.emit("leaveRoom", room);
this.setState({
chat: false
});
};
render() {
return (
<React.Fragment>
{this.state.chat === true ? (
<ChatroomWithSocket />
) : (
<h1> no chatroom </h1>
)}
<div>
<h1> Create your room </h1>
</div>
<div>
<form>
<textarea
name="room"
placeholder="Write.."
value={this.state.room}
onChange={ev => this.setState({ room: ev.target.value })}
/>
<button onClick={this.creatingRoom}>
Create
</button>
</form>
</div>
<div>
<h4> Rooms </h4>
<div>
<ul>
{this.state.rooms.map((room, index) => {
return (
<li key={index}>
<button href="#" onClick={this.joinRoom} value={room.room}>
Join {room.room}
</button>
<button href="#" onClick={this.leaveRoom} value=
{room.room}>
Leave {room.room}
</button>
</li>
);
})}
</ul>
</div>
</div>
</React.Fragment>
);
}
}
const HomeWithSocket = props => (
<SocketContext.Consumer>
{socket => <Home {...props} socket={socket} />}
</SocketContext.Consumer>
);
客户端(Chatroom.js)
class Chatroom extends Component {
constructor(props) {
super(props);
this.state = {
message: "",
messages: []
};
this.sendMessage = this.sendMessage.bind(this);
this.props.socket.on("receiveMessage", function(data) {
addMessage(data);
});
const addMessage = data => {
this.setState({ messages: [...this.state.messages, data] });
};
}
sendMessage(e) {
e.preventDefault();
this.props.socket.emit("sendMessage", {
message: this.state.message
});
this.setState({ message: "" });
}
render() {
return (
<React.Fragment>
<div className="messages">
{this.state.messages.map((message, key) => {
return <li key={key}>{message.message}</li>;
})}
</div>
<div>
<form onSubmit={this.sendMessage}>
<input
type="text"
placeholder="Message"
value={this.state.message}
onChange={ev => this.setState({ message: ev.target.value })}
/>
<button type="submit">
Send
</button>
</form>
</div>
</React.Fragment>
);
}
}
const ChatroomWithSocket = props => (
<SocketContext.Consumer>
{socket => <Chatroom {...props} socket={socket} />}
</SocketContext.Consumer>
);
服务器端(index.js)
var rooms = [];
io.on("connection", function(socket) {
socket.on("creatingRoom", function(room) {
rooms.push(room);
io.emit("createRoom", room);
});
socket.on("joinRoom", function(newRoom) {
socket.join(newRoom);
socket.room = newRoom;
});
socket.on("leaveRoom", function() {
socket.leave(socket.room);
});
socket.on("sendMessage", function(data) {
io.emit("receiveMessage", data);
});
});
解决方案
这个错误通常意味着它所说的,可能是内存泄漏。
根据我的怀疑,它可能来自套接字连接。这样看。。
在 中componentDidMount
,您设置了一个套接字连接。如果您在没有关闭套接字连接的情况下离开组件,您一定会收到此错误。我不确定您到底在做什么,但请尝试关闭其中的套接字componentWillUnmount
以查看它是否有效。
如果是这样,请考虑在导航时不会被破坏的组件中创建套接字,或将套接字连接存储在 Redux 中
推荐阅读
- ros - `roslaunch rosbridge_server rosbridge_websocket.launch` 需要停用 venv
- mongodb - 如何编写mongo查询
- javascript - 从二维数组中检索对角线值
- python-3.x - 如何将数据从点云文件写入文本文件
- voice - 日期输入视图需要哪些培训?
- docker - CircleCI Docker 构建没有通过 env vars
- python - 推送被拒绝,无法编译 Python 应用程序。| 我无法将 Django 应用程序部署到 Heroku
- javascript - 从动态加载的输入字段访问值
- authentication - 表示 PGP 密钥的人类可读方式(去中心化客户端身份验证)
- angularfire2 - Angularfire2 SSR:firebase 函数构建错误