错误:重新渲染过多。 React 限制了渲染的数量以防止无限循环。即使使用箭头函数
Posted
技术标签:
【中文标题】错误:重新渲染过多。 React 限制了渲染的数量以防止无限循环。即使使用箭头函数【英文标题】:Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. Even with arrow functions used 【发布时间】:2021-09-29 04:49:53 【问题描述】:所以我正在使用 react 、 redux 、 node 、 express 和 socket.io 创建一个实时聊天应用程序,我的代码在没有 addMessage 操作的情况下工作,即使我将其更改为 [...messages,message] 和使用 useState 定义消息,它仍然显示错误。
这是我发生错误的客户端代码。
import Header from "./Header";
import MessageBox from "./MessageBox";
import MessageBody from "./MessageBody";
import addMessage from "../actions"
import useEffect,useState from "react";
import connect from "react-redux";
import io from 'socket.io-client';
let socket;
const Chat = (name,addMessage) =>
const [message,setMessage] = useState('');
const ENDPOINT = 'localhost:5000';
useEffect(()=>
socket =io(ENDPOINT);
socket.emit('join',name,()=>
)
return ()=>
socket.disconnect();
socket.off();
,[name]);
useEffect(()=>
socket.on('message',(message)=>
addMessage(message)
console.log(message);
);
return ()=>
socket.off();
);
const sendMessage = (event)=>
event.preventDefault();
if(message)
socket.emit('sendMessage',message,()=>setMessage(''))
return (
<div style=backgroundColor:"#414a4c">
<Header/>
<MessageBody name=name/>
<MessageBox message=message setMessage=setMessage sendMessage=sendMessage/>
</div>
)
const mapStateToProps =(state)=>
return
name : state.enteredName
export default connect(mapStateToProps,addMessage)(Chat)
这是消息框组件
const MessageBox = (message,setMessage,sendMessage) =>
return (
<section className="bg-dark text-light p-1" style=style>
<div className="container">
<div className="d-flex justify-content-around align-items-center">
<div className="input-group news-input">
<input type="text" className="form-control"
value=message
onChange=( target: value ) => setMessage(value)
placeholder="Write Your Messages Here"
onKeyPress=(e)=>e.key==='Enter'&& sendMessage(e)
/>
</div>
<i className="bi bi-telegram ps-2 pb-1" style=fontSize:"40px"
onClick=(e)=> sendMessage(e)
>
</i>
</div>
</div>
</section>
)
const style =
position : "fixed",
bottom: "0px",
width:"100%"
export default MessageBox
这是服务器端代码
const express = require('express');
const socketio = require('socket.io');
const http = require('http');
const addUser,removeUser,getUser,getAllUsers = require('./users');
corsOptions=
cors: true,
origins:["http://localhost:3000"],
const PORT = process.env.PORT || 5000;
const router = require('./router');
const app = express();
const server = http.createServer(app);
const io = socketio(server, corsOptions);
io.on('connection',(socket)=>
socket.on('join',(name,callback)=>
const error,user = addUser(id:socket.id,name);
if(error)return callback(error);
socket.emit('message',user:'admin',text:`$user.name welcome to the chat.`);
socket.broadcast.emit('message',user:'admin',text:`$user.name has joined the chat`)
socket.join(user);
callback();
)
socket.on('sendMessage',(message)=>
const user = getUser(socket.id);
io.emit('message',user:user.name,text:message);
);
socket.on('disconnect',()=>
console.log("user just left");
socket.broadcast.emit('message',user:'admin',text:`$user.name has left the chat`)
)
)
app.use(router);
server.listen(PORT,()=>console.log(`The server is running on $PORT`));
完整代码位于:https://github.com/Pramil01/Globe-Chat.git>
【问题讨论】:
只使用一个useEffect语句 你可以使用多个 useEffect ,这不是问题。尝试将您的套接字存储在 useState 中,而不是全局变量并添加一个空的 useEffect 依赖项-> [ ] ,Check this out how u can store socket in useState 【参考方案1】:你必须指定
useEffect(()=>
socket.on('message',(message)=>
addMessage(message)
console.log(message);
);
return ()=>
socket.off();
, [] <- dependency array);
【讨论】:
即使我只是放空 [] 运行一次,它仍然显示错误。【参考方案2】:主要问题出在聊天框组件中,我在其中使用了 useState 并导致重新渲染,一旦删除代码现在可以正常工作。
【讨论】:
以上是关于错误:重新渲染过多。 React 限制了渲染的数量以防止无限循环。即使使用箭头函数的主要内容,如果未能解决你的问题,请参考以下文章
React 限制渲染次数以防止无限循环...重新渲染次数过多
太多的重新渲染。 React 限制了渲染的数量以防止无限循环。?
“错误:重新渲染过多。React 限制了渲染次数以防止无限循环。”