繁体   English   中英

如何在第一次渲染时获取套接字数据?

[英]How to get socket data on first render?

我正在尝试使用 React.JS 制作一个实时聊天应用程序。
用户创建用户名后,跳转到:/home。
所有连接的用户都将显示在 /home 中。

这是我编写的代码(ShowUser.js):

import React, { useState, useEffect } from "react";
import Context from "../../context/Context";
import { useContextSelector } from "use-context-selector";

export default function ShowUsers() {

    const socket = useContextSelector(Context, item => item.socket)
    const [ alluser, setAlluser ] = useState([])

    const get_data = () => {
        socket.on("send_users", (users) => {
            setAlluser(users)
        })
    }

    useEffect(() => {
        get_data()
        console.log(alluser)
        return () => {
            socket.off("send_users")
        }
    })

    return (
        <div style={{ background: "white" }}>
            {alluser.length}
        </div>
    )
}

服务器端:

const http = require("http");
const express = require("express");
const app = express();
const socketio = require("socket.io");
const cors = require("cors");
const server = http.createServer(app);
const io = socketio(server, {
    cors: {
        origin: "*",
    },
});

const users = [];

app.use(cors());

io.on("connection", (socket) => {
    console.log(socket.id);
    const id = socket.id;
    socket.on("create", (username, callback) => {
        //檢查user是否存在
        //存在 ? 提醒已存在 : 加入users && 將users給前端
        const existingUser = users.find((user) => user.username === username);

        if (existingUser) return callback("This username is been taken!");
        const user = { id, username };
        users.push(user);
        console.log(`${id} create ${username}`);

        io.emit("send_users", users);
    });

    socket.on("disconnect", () => {
        const id = socket.id;

        const index = users.findIndex((user) => user.id === id);

        if (index !== -1) {
            users.splice(index, 1)[0];
        }

        console.log(`${id} leave`);
    });
});

server.listen(process.env.PORT || 3300, () => {
    console.log(`running in 3300`);
});

useEffect 将在返回后执行。
所以 {alluser.length} 将为零。
我该如何解决这种情况?
我的英语不是很好。 请原谅我。

解决方案

主页.js

import React, { useState, useEffect } from "react";
import Context from "../../context/Context";
import { useContextSelector } from "use-context-selector";

export default function ShowUsers() {
    const socket = useContextSelector(Context, (item) => item.socket);
    const [alluser, setAlluser] = useState([]);

    const get_data = () => {
        socket.emit("load_users");
        socket.on("send_users", (users) => {
            setAlluser(users);
        });
    };

    useEffect(() => {
        get_data();
        console.log(alluser);
    }, []);

    return <div style={{ background: "white" }}>{alluser.length}</div>;
}

服务器端:

const http = require("http");
const express = require("express");
const app = express();
const socketio = require("socket.io");
const cors = require("cors");
const server = http.createServer(app);
const io = socketio(server, {
    cors: {
        origin: "*",
    },
});

const users = [];

app.use(cors());

io.on("connection", (socket) => {
    console.log(socket.id);
    const id = socket.id;
    socket.on("create", (username, callback) => {
        //檢查user是否存在
        //存在 ? 提醒已存在 : 加入users && 將users給前端
        const existingUser = users.find((user) => user.username === username);

        if (existingUser) return callback("This username is been taken!");
        const user = { id, username };
        users.push(user);
        console.log(`${id} create ${username}`);

        socket.on("load_users", () => {
            io.emit("send_users", users);
        });
    });

    socket.on("disconnect", () => {
        const id = socket.id;

        const index = users.findIndex((user) => user.id === id);

        if (index !== -1) {
            users.splice(index, 1)[0];
        }

        io.emit("send_users", users);
    });
});

server.listen(process.env.PORT || 3300, () => {
    console.log(`running in 3300`);
});

进行以下更改:

  1. 在服务器端添加socket.on("load_users" () => {...})
  2. 在客户端添加socket.emit("load_users")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM