简体   繁体   中英

too many re-renders. react limits the number of renders to prevent an infinite loop. UseEffect

Whenever I try to render my component, I am getting this error:

too many re-renders. react limits the number of renders to prevent an infinite loop.

I have tried using axios cancelToken and square brackets in useEffect hook. But nothing works. The code requests an array of notifications from server and store it in a state variable "notifications", using useState react hook. Here's my code:

 import React, {useState, useEffect} from 'react'; import NavbarComponent from './NavbarComponent'; import { Card, Button, Modal } from "react-bootstrap"; import axios from 'axios'; function Notifications({username}) { const [show, setShow] = useState(false); const [response, setresponse] = useState([]) const handleClose = () => setShow(false); const handleShow = () => setShow(true); const [notifications, setnotifictions] = useState([]) const [password, setpassword] = useState("") var user = { username: username } const CancelToken = axios.CancelToken; const source = CancelToken.source(); useEffect(() => { const fetchnoti = async () => { await axios.post('/api/getnoti', user, {cancelToken: source.token}).then(res => { console.log(res) setnotifictions(res.data) }).catch(err => { if (axios.isCancel(err)) { console.log('Request canceled', err.message); } else console.log(err) }) } fetchnoti(); return () => { source.cancel() } }, []) function accept(noti){ var param = { noti: noti, password: password } axios.post('/api/accepttxn', param).then(res => { console.log(res) setresponse(res.data) }).catch(err => { console.log(err) }) } function accepttxn(noti){ handleShow(); setresponse([]); setpassword(""); return( <div> <Modal show={show} onHide={handleClose}> <Modal.Header closeButton> <Modal.Title>Enter Password to Proceed</Modal.Title> </Modal.Header> <Modal.Body><input type="password" value={password} onChange={(event) => setpassword(event.target.value)}/></Modal.Body> <Modal.Footer> <Button variant="secondary" onClick={handleClose}> Close </Button> <Button variant="success" onClick={() => {accept(noti)}}> Proceed to Accept </Button> {response} </Modal.Footer> </Modal> </div> ); } function reject(noti){ var param = { noti: noti, password: password } axios.post('/api/rejecttxn', param).then(res => { console.log(res) setresponse(res.data) }).catch(err => { console.log(err) }) } function rejecttxn(noti){ handleShow(); setresponse([]); setpassword(""); return( <div> <Modal show={show} onHide={handleClose}> <Modal.Header closeButton> <Modal.Title>Enter Password to Proceed</Modal.Title> </Modal.Header> <Modal.Body><input type="password" value={password} onChange={(event) => setpassword(event.target.value)}/></Modal.Body> <Modal.Footer> <Button variant="secondary" onClick={handleClose}> Close </Button> <Button variant="danger" onClick={() => {reject(noti)}}> Proceed to Reject </Button> {response} </Modal.Footer> </Modal> </div> ); } const notis = notifications.map((noti) => { return( <Card key={noti.id}> <Card.Body> <Card.Text> Sender: {noti.sender} </Card.Text> <Card.Text> Amount: {noti.amount} </Card.Text> <Card.Text> {noti.message? <div>Message: {noti.message}</div>: null} </Card.Text> <Button variant="primary" onClick={ accepttxn(noti) }>Accept</Button> <Button variant="danger" onClick={ rejecttxn(noti) }>Reject</Button> </Card.Body> </Card> ) }) return ( <div> {notis.length? <div>{notis}</div>: <h1>No new notifications</h1>} </div> ); } export default Notifications;

Can anyone help me out?

It's not the useEffect probably, you have a button which calls a function whenever it renders:

<Button variant="danger" onClick={rejecttxn(noti)}>Reject</Button>

You could rewrite the function to return a function, it improves performance because you may re-render components that does not need to be rerendered when using inline functions, check below example:

function rejecttxn(noti){
    return function() {
    handleShow();
            
            
    setresponse([]); 
    setpassword("");
    return (
      <div>

        <Modal show={show} onHide={handleClose}>
          <Modal.Header closeButton>
            <Modal.Title>Enter Password to Proceed</Modal.Title>
          </Modal.Header>
          <Modal.Body><input type="password" value={password} onChange={(event) => setpassword(event.target.value)}/></Modal.Body>
          <Modal.Footer>
            <Button variant="secondary" onClick={handleClose}>
              Close
            </Button>
            <Button variant="danger" onClick={() => {reject(noti)}}>
              Proceed to Reject
            </Button>
            {response}
          </Modal.Footer>
        </Modal>
      </div>
    );
   } 
  }

Or using arrow functions:

const rejecttxn = (noti) => () => {
    handleShow();


    setresponse([]); 
    setpassword("");
    return (
      <div>

        <Modal show={show} onHide={handleClose}>
          <Modal.Header closeButton>
            <Modal.Title>Enter Password to Proceed</Modal.Title>
          </Modal.Header>
          <Modal.Body><input type="password" value={password} onChange={(event) => setpassword(event.target.value)}/></Modal.Body>
          <Modal.Footer>
            <Button variant="secondary" onClick={handleClose}>
              Close
            </Button>
            <Button variant="danger" onClick={() => {reject(noti)}}>
              Proceed to Reject
            </Button>
            {response}
          </Modal.Footer>
        </Modal>
      </div>
    );
   } 
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM