0

I have the common warning displaying upon loading of my web app but never again...

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

EDIT**** It is caused by this chunk of code. I have narrowed it down to one function. It blows up when I try to setMoisture state. I am not sure why.

function getData (){
    Axios.get("http://localhost:3001/api/get-value").then((response) => {
        const recievedData = response.data;
        const dataValue = recievedData.map((val) => {
            return [val.value]
        })
        if (loading === true){
            setLoading(false);
        }
        return parseInt(dataValue);
    }).then((resp)=>setMoisture(resp))
}

React.useEffect(() => {
    if (moisture === "initialState"){
        getData();
    }
}, []); 
Justin Oberle
  • 461
  • 1
  • 13

2 Answers2

1

Posting the answer here (based from the comments) for completeness.

Basically, use local variables and cleanup function towards the end of useEffect(). Using this as reference:

Similar situation here

Andy Refuerzo
  • 3,154
  • 1
  • 29
  • 37
0

You should declare the function inside the useEffect or add it as a dependency. one way to do it's just moving your function inside the hook.

  // I assumed that your useState hooks looks something similar.
  const [moisture, setMoisture] = React.useState('initialState')
  const [loading, setLoading] = React.useState(true)

  React.useEffect(() => {
    function getData() {
      Axios.get("http://localhost:3001/api/get-value").then((response) => {
        const recievedData = response.data;
        const dataValue = recievedData.map((val) => {
          return [val.value]
        })
        if(loading === true) {
          setLoading(false);
        }
        return parseInt(dataValue);
      }).then((resp => setMoisture(resp)))
    }

    if (moisture === "initialState"){
      getData();
    }

  }, [])

You also probably want to first set your data to the state and then change your loading state to false, this is gonna prevent some bugs. This is another way to do it and manage the loading state and the promises

  React.useEffect(() => {
    function getData() {
      setLoading(true)
      Axios.get("http://localhost:3001/api/get-value")
        .then((response) => {
          const dataValue = response.data.map((val) => {
            return [val.value]
          })
          // This is going to pass 0 when can't parse the data
          setMoisture(parseInt(dataValue) || 0)
          setLoading(false)
        })
    }

    getData()
  }, [])
edgarlr
  • 387
  • 3
  • 5