【发布时间】:2021-03-22 23:51:30
【问题描述】:
我有这段代码,它基本上是一个 WIP 页面,用于我正在开发的简单聊天应用程序,作为我的教师课程的一部分。
我正在从服务器获取套接字,并且可以在主组件上毫无问题地使用它,但在子组件中它始终是 undefined。
主要组件:
import React, { FormEvent } from 'react';
import { asyncConnect } from '../utils/index';
import {
socketEvents,
SendActiveUsersMessage
} from '../types';
import { Socket } from 'socket.io-client';
import Home from './Home';
export default function RegisterUser() {
let socket: typeof Socket;
const [username, setUsername] = React.useState<string>("");
const [badUsername, setBadUsername] = React.useState<boolean>(true);
const [errorMsg, setErrorMsg] = React.useState<string>("");
const [signupSuccessful, setSignupSuccesful] = React.useState<boolean>(false);
const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (username === "") {
setBadUsername(true)
return;
} else {
setBadUsername(false);
}
socket = await asyncConnect();
if(!socket) {
setErrorMsg('Backend unreachable');
}
socket.emit(socketEvents.SEND_USERNAME, {
username
});
socket.on(socketEvents.SEND_ACTIVE_USERS, (msg: SendActiveUsersMessage) => {
console.log('activeUsers: ', msg.activeUsers);
});
setSignupSuccesful(true);
}
const handleInputChange = (e: React.FormEvent<HTMLInputElement>) => {
setUsername(e.currentTarget.value);
}
const generateErrorMessageIfNeeded = () => {
let error = errorMsg;
if (badUsername) {
error += "User name must not be empty\n";
}
return (
<h3>{error}</h3>
)
}
const generateInputForm = () => {
return (
<div>
<form onSubmit={handleSubmit}>
<h2>Enter username</h2>
<input
type='text'
id='username'
onChange={handleInputChange}
/>
<button type="submit">Submit</button>
</form>
<div>{generateErrorMessageIfNeeded()}</div>
</div>
)
}
const render = () => {
if(signupSuccessful) {
return <Home socket={socket as typeof Socket}/>
} else {
return generateInputForm();
}
}
return render();
}
asyncConnect 函数如下所示:
import io, { Socket } from 'socket.io-client';
import { socketEvents } from '../types';
export const asyncConnect = async():Promise<typeof Socket> => {
return new Promise( (resolve, _reject) => {
setTimeout(() => {
const socket = io.connect(process.env.REACT_APP_SERVER_URL as string);
socket.on(socketEvents.CONNECT, () => {
resolve(socket)
});
}, 500)
});
}
Home 组件,我将套接字传递到该组件,如下所示:
import { Socket } from "socket.io-client"
interface Props {
socket: typeof Socket
}
export default function Home (props: Props) {
console.log('props from Home component: ', props);
return (
<h2>Home </h2>
)
}
将套接字保存到状态
我尝试过的另一件事是为套接字创建状态(类似于 4 个已经存在的状态)。但是当我尝试这样做时,在我保存状态并尝试使用状态内部的套接字后,我得到socket.emit is not a function 错误。
感谢任何形式的帮助,因为我不知道我做错了什么。
【问题讨论】:
标签: reactjs typescript socket.io react-state-management