function Reply({ id, user }) {
const [data, setData] = useState([]);
const [replyText, setReplyText] = useState("");
useEffect(() => {
async function fetchData() {
const response = await _axios.get("/reply/" id);
setData(response.data);
}
fetchData();
}, [data]); <---- ** problem ** with data(dependency),
infinite request(call) fetchData()
...
}
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
what's the reason for infinite loop if there's a dependency. as far as i know, when dependency(data) change, re-render. but useEffect keep asking for data(axios.get(~~)). if i leave a comment, i can see normally the latest comments, but the network tab(in develop tools) keeps asking for data(304 Not Modified, under image)
CodePudding user response:
There's an infinite loop because that code says "If data
changes, request information from the server and change data
." The second half of that changes data
, which triggers the first half again.
You're not using data
in the callback, so it shouldn't be a dependency. Just remove it:
useEffect(() => {
async function fetchData() {
const response = await _axios.get("/reply/" id);
setData(response.data);
}
fetchData();
}, []);
// ^^−−−−−−−−−− don't put `data` here
That gives you a blank dependency array, which will run the effect only when the component first mounts. (If you want to run it again after mount, use a different state member for that, or define fetchData
outside the effect and use it both in the effect and at the other time you want to fetch data.)
Side note: Nothing in your code is handling rejections from your fetchData
function, which will cause "unhandled rejection" errors. You'll want to hook up a rejection handler to report or suppress the error.
CodePudding user response:
You are using setData
after the response which causes the data to change and hence the useEffect(() => {<>your code<>} ,[data])
to fire again.
use useEffect(() => {<>your code<>},[])
if you want to execute the AJAX call only once after component mounting
or
use useEffect(() => {<>your code<>})
without the dependency if you want to execute the AJAX call after the component mount and after every update
CodePudding user response:
Dependencies argument of useEffect
is useEffect(callback, dependencies)
Let's explore side effects and runs:
Not provided: the side-effect runs after every rendering.
import { useEffect } from 'react';
function MyComponent() {
useEffect(() => {
// Runs after EVERY rendering
});
}
An empty array []: the side-effect runs once after the initial rendering.
import { useEffect } from 'react';
function MyComponent() {
useEffect(() => {
// Runs ONCE after initial rendering
}, []);
}
Has props or state values [prop1, prop2, ..., state1, state2]
: the side-effect runs only when any dependency value changes.
import { useEffect, useState } from 'react';
function MyComponent({ prop }) {
const [state, setState] = useState('');
useEffect(() => {
// Runs ONCE after initial rendering
// and after every rendering ONLY IF `prop` or `state` changes
}, [prop, state]);
}