NodeJS React JS应用在聊天应用中重新加载时呈现白色页面:如何解决?

3pvhb19x  于 12个月前  发布在  Node.js
关注(0)|答案(1)|浏览(118)

问题很简单。我有一个“主”页面,它通过一个表单收集数据,并将数据发送到“聊天”页面。在我重新加载聊天页面之前,一切都很好,这使得所有内容都是空白的白色。控制台中没有错误。此时的url应该有用户名和聊天室的名称,据我所知,这仍然存在于url中,即使在重新加载页面并获得空白白色页面之后。
这似乎是一个流行的问题,但到目前为止,没有一个建议的解决方案对我有效。这是我尝试过的:

  • 在package.json中更改了“主页”
  • 尝试了整个

/* index.html 200

  • 已尝试HashRouter而不是BrowserRouter,已尝试为Router包含bashRouter,已尝试包含browserhistory
  • 尝试降级react到早期版本

到目前为止,这些都对我不起作用。这里是一个现场链接到网站:https://cyberpunk-chat.onrender.com/
下面是github repo:https://github.com/mohanamisra/chat-app-full-code
这里有一些相关的代码,以防万一:
导入路由器的页面:

在App.js中

import React from 'react';
import {BrowserRouter as Router, Route, Routes} from 'react-router-dom';
import Join from './components/Join/Join';
import Chat from './Chat';

const App = () => {
    return (
        <Router basename = "/">
            <Routes>
                <Route path='/' element={<Join/>}/>
                <Route path='/chat' element={<Chat/>}/>
            </Routes>
        </Router>
    );
};

export default App;

字符串

IN Chat.js

import React from 'react';
import {useState, useEffect} from 'react';
import queryString from 'query-string';
import { useNavigate } from 'react-router-dom';
import io from 'socket.io-client';
import InfoBar from "./components/InfoBar/InfoBar";
import Input from "./components/Input/Input";
import Messages from "./components/Messages/Messages";
import TextContainer from "./components/TextContainer/TextContainer";

import './Chat.css';
const ENDPOINT = 'https://cyberpunkchat.onrender.com';

let socket;

const Chat = () => {
    const navigate = useNavigate();
    const [name, setName] = useState('');
    const [room, setRoom] = useState('');
    const [messages, setMessages] = useState([]);
    const [message, setMessage] = useState('');
    const [users, setUsers] = useState('');

    useEffect(() => {
        const {name, room} = queryString.parse(window.location.search);
        socket = io(ENDPOINT, {transports:['websocket']});
        if(!name || !room) {
            console.log('I forgot...');
        }
        else {
            setName(name);
            setRoom(room);
            socket.emit('join', {name, room}, () => {
            });
        }
    }, [ENDPOINT, navigate]);

    useEffect(() => {
        socket.on('message', (message) => {
            setMessages([...messages, message]);
        })
        socket.on("roomData", ({ users }) => {
            setUsers(users);
        });
    }, [messages]);

    const sendMessage = (event) => {
        event.preventDefault();
        if(message)
            socket.emit('sendMessage', message, () => setMessage(''));
    }

    return(
        <div className = 'outerContainer'>
            <TextContainer users = {users}/>
            <div className = 'container'>
                <InfoBar room = {room}/>
                <Messages messages = {messages} name = {name}/>
                <Input message = {message} setMessage={setMessage} sendMessage={sendMessage}/>
            </div>
        </div>
    )
}

export default Chat;


我会很感激任何帮助的。
先谢谢你了!

xtfmy6hx

xtfmy6hx1#

当运行你的代码时,我无法加入聊天室并发送消息。除了页面重新加载问题之外,还有很多问题。下面是你的代码中的几个问题:
1.在chat.js中,第二个useEffect钩子中没有定义socket
1.在chat.js中,在第一个钩子中可能会有一些名称冲突,因为变量nameroom与函数作用域中定义的变量一致。
1.在users.js中,您需要在修剪之前检查nameroom是否已定义。如果nameroom在客户端未定义,则会导致服务器崩溃。

  1. TypeIt在从DOM卸载时导致与childNodes相关的错误。我试图更新代码以使其工作,但如果问题仍然存在,请从代码中删除TypeIt
  2. Join.js中的表单提交工作不正常。
    1.在index.js(服务器)上的sendMessage事件中,如果找不到用户,服务器将崩溃。

溶液

下面是解决上述所有问题的解决方案。在将代码部署到Render之前,不要忘记更新ENDPOINT

Chat.js(客户端)

import React from "react";
import { useState, useEffect } from "react";
import io from "socket.io-client";
import InfoBar from "./components/InfoBar/InfoBar";
import Input from "./components/Input/Input";
import Messages from "./components/Messages/Messages";
import TextContainer from "./components/TextContainer/TextContainer";
import { useLocation } from "react-router";

import "./Chat.css";
const ENDPOINT = "http://localhost:5000";
const socket = io(ENDPOINT, {
  transports: ["websocket"],
});

const Chat = () => {
  const [name, setName] = useState("");
  const [room, setRoom] = useState("");
  const [messages, setMessages] = useState([]);
  const [message, setMessage] = useState("");
  const [users, setUsers] = useState("");
  let location = useLocation();

  useEffect(() => {
    const info = location.state;
    const query_name = info.name;
    const query_room = info.room;
    console.log(query_name, query_room);
    if (!query_name || !query_room) {
      console.log("I forgot...");
    } else {
      setName(query_name);
      setRoom(query_room);
      socket.emit("join", { name: query_name, room: query_room }, () => {});
    }

    socket.on("message", (new_message) => {
      setMessages([...messages, new_message]);
    });

    socket.on("roomData", ({ users }) => {
      setUsers(users);
    });
  }, [messages, location]);

  const sendMessage = (event) => {
    event.preventDefault();
    if (message) socket.emit("sendMessage", message, () => setMessage(""));
  };

  return (
    <div className="outerContainer">
      <TextContainer users={users} />
      <div className="container">
        <InfoBar room={room} />
        <Messages messages={messages} name={name} />
        <Input
          message={message}
          setMessage={setMessage}
          sendMessage={sendMessage}
        />
      </div>
    </div>
  );
};

export default Chat;

字符串

Join.js(客户端)

import React from "react";
import { useState } from "react";
import { useNavigate } from "react-router-dom";
import TypeIt from "typeit-react";
import "./Join.css";

const Join = () => {
  const [name, setName] = useState("john");
  const [room, setRoom] = useState("room1");
  const navigate = useNavigate();

  const handleNameChange = (event) => {
    const newName = event.target.value;
    setName(newName);
  };

  const handleRoomNameChange = (event) => {
    const newRoom = event.target.value;
    setRoom(newRoom);
  };

  const handleButtonClick = (event) => {
    event.preventDefault();

    if (!name || !room) return;

    navigate("/chat", { state: { name, room } });
  };

  return (
    <div className="joinOuterContainer">
      <div className="joinInnerContainer">
        <TypeIt
          className="heading"
          getBeforeInit={(instance) => {
            instance.type("Login!").pause(1000).delete(1).pause(500).type("");
            return instance;
          }}
          options={{
            speed: 60,
            waitUntilVisible: true,
          }}
        />
        <form className="form">
          <div>
            <input
              placeholder="Enter name"
              className="joinInput"
              type="text"
              onChange={handleNameChange}
            />
          </div>
          <div>
            <input
              placeholder="Enter room name"
              className="joinInput"
              type="text"
              onChange={handleRoomNameChange}
            />
          </div>

          <button onClick={handleButtonClick} className="button">
            Sign In
          </button>
        </form>
      </div>
    </div>
  );
};

export default Join;

users.js(服务器端)

const users = [];

const addUser = ({ id, name, room }) => {
  if (!name || !room) return;
  name = name.trim().toLowerCase();
  room = room.trim().toLowerCase();

  const existingUser = users.find(
    (user) => user.room === room && user.name === name
  );
  if (existingUser) {
    return {
      error: "Username is taken in this room.",
    };
  }
  const user = { id, name, room };
  users.push(user);
  return { user };
};

const removeUser = (id) => {
  const index = users.findIndex((user) => user.id === id);
  if (index !== -1) return users.splice(index, 1)[0];
};

const getUser = (id) => {
  return users.find((user) => user.id === id);
};

const getUsersInRoom = (room) => {
  return users.filter((user) => user.room === room);
};

module.exports = { addUser, removeUser, getUser, getUsersInRoom };

index.js(服务器端)

仅修改以下内容:

socket.on('sendMessage', (message, callback) => {
        const user = getUser(socket.id);
        if(!user)return; // ! important
        io.to(user.room).emit('message', {user: user.name, text: message});
        callback();
    });

页面重载问题

在localhost上,我无法重现您所说的页面重新加载问题。请发布您的渲染Web服务的完整日志。

相关问题