【问题标题】:React socket io client emitting twice to node server反应套接字 io 客户端向节点服务器发出两次
【发布时间】:2021-09-30 20:26:39
【问题描述】:

我正在制作一个以节点为后端的反应应用程序。他们使用 socket-io 进行通信。我遇到的问题是 react 确实和 emit 将数据发送到节点,但是做了两次,从而进行了双重提交。例如,使用登录表单,终端输出如下所示:

[nodemon] starting `node --trace-warnings central-server.js`
web server running on port 5000
client GuRD1JAb_J1xn4O4AAAB successfully connected
{ CompanyID: 'BigCompany', Password: 'SecretPassword' }
{ CompanyID: 'BigCompany', Password: 'SecretPassword' }

这是前端应用程序:

import { useState } from "react";
import Form from "./components/Signup-Form.js";
import { io } from "socket.io-client";
const socket = io("http://192.168.43.118:5000", {
    withCredentials: true,
    extraHeaders: {
        "react-client": "react-client",
    },
});
function App() {
    const [userData, setUserData] = useState({});

    if (Object.entries(userData).length === 0) {
        return (
            <div className="App">
                <div className="textContainer">
                    <h1>Welcome</h1>
                    <h3>You can Log in or Sign Up here</h3>
                </div>
                <Form setUserData={setUserData} />
            </div>
        );
    } else {
        socket.emit("signup", userData);
        return <p>Data sent successfully</p>;
    }
}

export default App;

服务器:

var express = require("express");
var app = express();
var server = require("http").Server(app);

const dotenv = require("dotenv");
dotenv.config();
const WS_PORT = process.env.PORT || 5000;
const io = require("socket.io")(server, {
    cors: {
        origin: ["http://localhost:3000", "http://192.168.43.118:3000"],
        methods: ["GET", "POST"],
        transports: ["websocket", "polling", "flashsocket"],
        allowedHeaders: ["react-client"],
        credentials: true,
    },
});
io.on("connection", (socket) => {
    console.log(`client ${socket.id} successfully connected`);
    socket.on("signup", (data) => {
        console.log(data);
    });
});
server.listen(WS_PORT, () => console.log("web server running on port", WS_PORT));

App.js 文件是目前唯一使用套接字的文件。此外,当我保存文件并且服务器自动重新加载时,我让客户端创建了 3 次连接,而不仅仅是一次。

【问题讨论】:

    标签: javascript node.js reactjs sockets socket.io


    【解决方案1】:

    您不应该在渲染代码中执行异步或事件驱动的操作。每次你的App 组件被渲染时(例如当状态改变时),如果userData 仍然是空的,它也会再次执行你的socket.emit

    由于是什么导致 App 渲染两次,我无法从您的代码中看出。但是你应该假设 React 可以在任何时候重新渲染你的组件,所以尽量避免这样的问题。

    您可以将React.useEffect[] 的依赖关系数组一起使用,以便在组件安装时仅执行一次操作。在您的情况下,最好只进行常规回调:

    import { useEffect, useState } from "react";
    
    
    function App() {
        const [dataSent, setDataSent] = useState(false);
    
        const sendData = (data) => {
            if (dataSent) return; // Just to make sure
            socket.emit('signup', data);
            setDataSent(true);
        };
    
        // If you want to actuall wait for a response to display:
        const [response, setResponse] = useState(undefined);
        useEffect(() => {
            socket.on('signup-response', setResponse);
            return () => {
                // This function gets called when the effect gets retriggered
                // (which never happens because of the [] dependency array)
                // or if the component gets unmouted.
                // We remove the event listener here:
                socket.off('signup-response', setResponse);
            };
        }, []);
        if (response) return <p>Got response: {response}</p>;
    
    
        if (dataSent) {
            return <p>Data sent successfully</p>;
        } else {
            return (
                <div className="App">
                    <div className="textContainer">
                        <h1>Welcome</h1>
                        <h3>You can Log in or Sign Up here</h3>
                    </div>
                    <Form setUserData={sendData} />
                </div>
            );
        }
    }
    

    我添加了一种方式,让您可以收听服务器的响应。您可以将它用于任何数据/事件,服务器也可以发送多次。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-28
      • 2014-02-04
      • 2015-06-15
      相关资源
      最近更新 更多