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.