I'm trying to build a react component that is showing a random number based of an API response. But I notice that the number displayed is infinitely re-rendered and it when I check the server console, it receives infinite request from react. How to solve this? I am using react state to display the number.
API randomnumber.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function (req, res, next) {
let randomNumber = Math.floor(Math.random() * 100);
res.send({
"number": randomNumber
})
});
module.exports = router;
React Component
import react, { useEffect, useState } from "react"
import axios from 'axios'
interface Props {
}
export default function RandomNumber(props: Props) {
const [number, setNumber] = useState(0);
axios({
method: "get",
url: "/api/random-number",
}).then(
((result) => {
setNumber(result.data.number)
})
)
return (
<>
<h1>{number}</h1>
</>
)
}
I want the server to return 1 random number per request, and react will render that number.
CodePudding user response:
You have to do the side-effects in useEffect Hook or you can use libraries like TANstack query etc., but it depends and a simple one like so should do the job ...
export default function RandomNumber(props: Props) {
const [number, setNumber] = useState(0);
React.useEffect(() => {
axios({
method: "get",
url: "/api/random-number",
}).then((result) => {
setNumber(result.data.number);
});
}, []); // `[]` means run the effect once on mount
return (
<>
<h1>{number}</h1>
</>
);
}
- In your code, what is really happening is, on every render, the
axios
call happens and it sets a new state which causes a re-render again and the same cycle repeats which cause infinite requests
CodePudding user response:
You can't update state as you do in your sample, because every setState
call will trigger re-rendering and will re-evaluate your code again ending up in infinite loop. Instead you should be calling your fetching logic "onComponentMount" with useEffect hook and empty dependency array:
useEffect(() => {
axios({
method: "get",
url: "/api/random-number",
}).then(
((result) => {
setNumber(result.data.number)
})
)
}, [])