错误:重新渲染过多。 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 限制了渲染次数以防止无限循环。”

收到此错误:错误:重新渲染过多。 React 限制渲染次数以防止无限循环

React Hooks:切换模式下的重新渲染次数过多

太多的重新渲染。 React 限制了渲染的数量以防止无限循环。 UI 和控制台错误