1

When I am adding addData or updateData to the array of useEffect, it gets called infinite times,but i think it should only be called when button is clicked.

import axios from 'axios' import { Button, TextField } from '@material-ui/core' import React,{useState,useEffect} from 'react' import { useDispatch, useSelector } from 'react-redux' import Applebar from './MainPage/Applebar' import './style.css' import { add } from '../reducers/data/dataReducer' import Loader from './Loader/Loader' const Main = () => { const user=useSelector(state => state.auth); const dispatch=useDispatch() const [data,setData]=useState({ site:"", uname:"", password:"" }) const handleChange=(e)=>{ setData({...data, [e.target.name]:e.target.value}) } const addData=async(e)=>{ console.log('add fun called') e.preventDefault() await axios.post('http://localhost:5000/data', data,{ withCredentials: true }); } const userData=useSelector(state=>state.data) const arrData=userData.data const deleteData=async(id)=>{ await axios.put("http://localhost:5000/data",{id},{ withCredentials: true }) } const editData=(id)=>{ const {data}=userData const reqdData=data.filter((d)=>{return (d._id==id)}) const [getData]=reqdData setData( { site:getData.site, uname:getData.uname, password:getData.password }) setCurrentId(id) } const [currentId,setCurrentId]=useState(null) const updateData=async()=>{ if(currentId!==null) console.log(currentId) const updateData=await axios.put("http://localhost:5000/update",{...data,_id:currentId},{ withCredentials: true }) console.log(updateData) } const getData=async()=>{ const data=await axios.get('http://localhost:5000/data',{ withCredentials: true }).then((response)=>{ dispatch(add(response.data)) }) } useEffect(()=>{ console.log("useeffect called") getData() },[dispatch])//, addData, updateData oncalling these function infinite calling return ( <div> <Applebar /> <h1>{user?.currentUser?.name}</h1> <div className="main_body"> <div className="main_form"> <form> <div className="form_field"> <TextField id="outlined-basic" name="site" label="site" variant="outlined" value={data.site} onChange={handleChange}/> </div> <div className="form_field"> <TextField id="outlined-basic" name="uname" label="uname" variant="outlined" value={data.uname} onChange={handleChange}/> </div> <div className="form_field"> <TextField id="outlined-basic" name="password" label="password" variant="outlined" value={data.password} onChange={handleChange}/> </div> <div className="form_field"> <Button onClick={addData} color="primary" variant="contained" >Add</Button></div> <div className="form_field"> <Button onClick={updateData} color="primary" variant="contained" >Update</Button></div> </form> </div> <div className="main_data"> {arrData?.map((data)=>{ return( <div key={data._id}> {data.site} <button onClick={()=>{deleteData(data._id)}}>-</button> <button onClick={()=>{editData(data._id)}}>editData</button> </div> ) })} </div> </div> </div> ) } //} export default Main 
11
  • pastebin.com/raw/wpRLZWHG Commented Feb 13, 2021 at 12:48
  • What was the reason behind adding a dependency on [dispatch] to your useEffect? Commented Feb 13, 2021 at 12:53
  • I am trying to fetch data from my local express server Commented Feb 13, 2021 at 12:55
  • what i want to achieve here is when i click on any of the following button addData or updateData the browser should display the updated page Commented Feb 13, 2021 at 13:02
  • but its working fine when i am using only dispatch button but then i have to refresh the page to get the updated page Commented Feb 13, 2021 at 13:03

2 Answers 2

1

useEffect(callback, dependencies) is the hook that manages the side-effects in functional components. The callback argument is a function to put the side-effect logic. dependencies is a list of dependencies of your side-effect: being props or state values.

useEffect(callback, dependencies) invokes the callback after initial mounting, and on later renderings, if any value inside dependencies has changed.

If you change one of the dependencies, the effect function will be executed. If you change a dependency in the effect function you will have an infinite loop.

Sign up to request clarification or add additional context in comments.

Comments

1

getData() updates the state, due to the dispatch to redux state, which causes the state to change, which in turn will re-render your component. On re-render all the defined functions will be redefined, hence the functions will change.

useEffect() will run everytime something in the dependency array changes, so it will run in an infinite loop due to the state changing and the functions being re-made every time the component re-renders.

You can use useCallback() to fix it. useCallback() will return any function defined inside it and will only redeclare the function when something in the useCallback() dependency array changes.

You can try to do this with your code

import {useCallback} from 'react' const addData= useCallback(async(e)=>{ console.log('add fun called') e.preventDefault() await axios.post('http://localhost:5000/data', data,{ withCredentials: true }); }, []) const updateData=useCallback(async()=>{ if(currentId!==null) console.log(currentId) const updateData=await axios.put("http://localhost:5000/update",{...data,_id:currentId},{ withCredentials: true }) console.log(updateData) }, []) useEffect(()=>{ console.log("useeffect called") getData() },[dispatch]) // now you can put those dependencies in this array, // even though you only need to add getData. You don't even need dispatch here 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.