谁能告诉我这个套接字事件怎么了?

时间:2020-04-17 03:24:34

标签: javascript reactjs socket.io react-hooks dom-events

我在用户加入和离开时发出了两个事件(user_joineduser_left)。它在服务器端工作,但不在客户端工作。

服务器端代码:(正在运行,在每个连接上均显示console.log)

io.on('connection', function (socket) {
    const id = socket.id;

    /**
     * User Join Function
     */
    socket.on('join', function ({ name, room }) {
        const { user } = addUser({id, name, room}); // add user to users array
        socket.join(user.room);
        socket.emit('user_joined', users); // emit event with modified users array
        console.log(id, 'joined')
    })

    /**
     * User Disconnect function
     */
    socket.on('disconnect', () => {
        removeUser(id); // remove user form users array
        socket.emit('user_left', users);  // emit event with modified users array
        console.log(id, 'left')
    })


})

客户端代码:(不在user_joineduser_left上触发)

const [players, setPlayers] = useState([]);

const ENDPOINT = 'localhost:5000';
socket = io(ENDPOINT);

useEffect(() => {
    const name = faker.name.firstName() + ' ' + faker.name.lastName();
    socket.emit('join', {name, room: 'global'}); // it's working fine

    return () => {
        socket.emit('disconnect');
        socket.off();
    }

}, [])

useEffect(() => {

    socket.on('user_joined', (users) => {
        setPlayers(users);
    }); // >>> Not Working <<<

    socket.on('user_left', (users) => {
        setPlayers(users);
    }); // >>> Not Working <<<

    console.log(socket) // it's working fine

}, [players]);

1 个答案:

答案 0 :(得分:1)

socket实例仅需要创建一次。就您而言,它是在每次重新渲染时创建的。另外,您不需要2 useEffects

放置socket实例的创建并将您的2 useEffects合并为1,并提供一个空数组作为依赖项。这样,您的useEffect仅执行一次,而不是在每次重新渲染时执行。

尝试一下

const [players, setPlayers] = useState([]);

useEffect(() => {
    const ENDPOINT = 'localhost:5000';
    socket = io(ENDPOINT);

    const name = faker.name.firstName() + ' ' + faker.name.lastName();
    socket.emit('join', {name, room: 'global'});

    socket.on('user_joined', (users) => {
        setPlayers(users);
    });

    socket.on('user_left', (users) => {
        setPlayers(users);
    });

    console.log(socket);

    return () => {
        socket.emit('disconnect');
        socket.off();
    }

}, []);
...

如果要在组件的其他位置使用套接字实例,请使用useRef。使用useRef,除非您对其进行了突变,否则总会得到相同的实例。

使用refs

创建套接字
...
const [players, setPlayers] = useState([]);
const ENDPOINT = 'localhost:5000';

const socketInstance = useRef(io(ENDPOINT));// in react, with useRef, you always get the same instance unless you mutate it.
useEffect(() => {
    // socketInstance.current = io(ENDPOINT);

    const name = faker.name.firstName() + ' ' + faker.name.lastName();
    socketInstance.current.emit('join', {name, room: 'global'});

    socketInstance.current.on('user_joined', (users) => {
        setPlayers(users);
    });

    socketInstance.current.on('user_left', (users) => {
        setPlayers(users);
    });

    console.log(socketInstance.current);

    return () => {
        socketInstance.current.emit('disconnect');
        socketInstance.current.off();
    }

}, []);
...
相关问题