Socket.io 发出未定义的变量 React

IT技术 html reactjs react-native sockets websocket
2021-05-07 09:20:32

我目前有一个非常简单的应用程序,它通过 websocket 连接向服务器发送和接收数据。本质上,该应用程序包含两个文本框,每次用户单击任一文本框以聚焦或单击离开时,都会向服务器发送通知,然后服务器将该消息广播到所有连接的实例。

这是我的代码如下:

App.js(客户端)

import React, { useState, useEffect } from 'react'
import io from 'socket.io-client'
import TextField from '@material-ui/core/TextField'
import './App.css'
import 'carbon-components/css/carbon-components.min.css';
import { TextArea } from 'carbon-components-react';

const socket = io.connect('http://localhost:4000')

function App() {

  const [myUser, setMyUser] = useState(null)

  const handleButtonClick = (e) => {
    e.preventDefault();
    setMyUser(e.target.value)
  }

  useEffect(() => {
    socket.on("message", ({ user, id, focus }) => {
      console.log(user, "clicked on", id, "with focus", focus)
    })
  }, [])

  function setFocusTrue(id) {
    const focus = true
    console.log("emitting: ", myUser, id, focus)
    socket.emit('message', { myUser, id, focus })
  }

  function setFocusFalse(id) {
    const focus = false
    console.log("emitting: ", myUser, id, focus)
    socket.emit('message', { myUser, id, focus })
  }

  const Main = () => {
    
    return (
      <div>
        <h1>Hello {myUser}</h1>
        <TextArea
            cols={50}
            helperText="Optional helper text here; if message is more than one line text should wrap (~100 character count maximum)"
            id="text1"
            invalidText="Invalid error message."
            labelText="Text area label"
            placeholder="Placeholder text"
            rows={4}
            onFocus={() => setFocusTrue('text1')}
            onBlur={() => setFocusFalse('text1')}
        />
        <TextArea
            cols={50}
            helperText="Optional helper text here; if message is more than one line text should wrap (~100 character count maximum)"
            id="text2"
            invalidText="Invalid error message."
            labelText="Text area label"
            placeholder="Placeholder text"
            rows={4}
            onFocus={() => setFocusTrue('text2')}
            onBlur={() => setFocusFalse('text2')}
        />
      </div>
    )
  }

  return (
    <div>
      {myUser === null ? 
        [
          <div>
            <button onClick={handleButtonClick} value="user1">User 1</button>
            <button onClick={handleButtonClick} value="user2">User 2</button>
          </div> 
        ]
        : <Main />
      }
    </div>
  )
}

export default App

index.js(服务器)

const app = require('express')()
const http = require('http').createServer(app)
const io = require('socket.io')(http)

io.on('connection', socket => {
  socket.on('message', ({ user, id, focus }) => {
    console.log('received user', user, 'id', id, 'focus', focus)
    io.emit('message', { user, id, focus })
  })
})

http.listen(4000, function() {
  console.log('listening on port 4000')
})

需要注意的一件事是,我正在用两个不同的用户(在两个隐身浏览器上运行)进行测试,因此每个用户都有条件呈现。对于此示例,当用户单击或远离文本框时,我可以看到文本框idfocus都是有效的,但由于某种原因,user未定义。我可以看到实例按预期发出变量,但它们没有在服务器中正确接收。

在这种特殊情况下,用户 1 单击第一个文本框(从而将焦点呈现为真)。设置要发送到服务器的每个变量(如控制台日志所示)。服务器接收焦点和 id 变量,但出于奇怪的原因,用户未定义,即使它存在。最后,广播消息被发送到两个实例,但如前所述,id并且focus存在,但user未定义。请参阅下面的屏幕截图。

客户端

客户端

服务器端控制台

在此处输入图片说明

1个回答

socket.emit('message', { myUser, id, focus })我没有像 那样发射对象,而是提供了用户对象,socket.emit('message', { user: myUser, id, focus })这似乎工作正常。