JangoCG
JangoCG

Reputation: 986

React Hook useEffect has a missing dependency Either include it or remove the dependency array react-hooks/exhaustive-deps

My react app gives me this warning:

React Hook useEffect has a missing dependency Either include it or remove the dependency array react-hooks/exhaustive-deps

If I move my Stateful components to the inside of the useEffect hook, then my Buttons can't access setButton anymore. Is there any way to fix this issue?

  const [value, setValue] = useState([])
  const [isLoading, setLoading] = useState(false)
  const [buttonValue, setButton] = useState(false)

This is my useEffect Hook

  useEffect(() => {
    axios.get('http://localhost:5000/').then(res => setValue(res.data))

    if (buttonValue === 'delete') {
      setLoading(true)
      axios.delete('http://localhost:5000/delete').then(() => {
        setLoading(false)
        setButton(null)
      })
    } else if (buttonValue === 'create') {
      setLoading(true)
      axios.post('http://localhost:5000/').then(() => {
        setLoading(false)
        setButton(null)
      })
    }
  }, [isLoading])

These are my Buttons

   <Form>
     <Form.Group>
       <Button variant='success' className='button' onClick={() => setButton('create')} id='create'>Create Sales Order</Button>
     </Form.Group>
     <Form.Group>
       <Button variant='danger' className='button' onClick={() => setButton('delete')} id='delete'>Delete Sales Order</Button>
     </Form.Group>
   </Form>

Upvotes: 1

Views: 7985

Answers (1)

Arman Safikhani
Arman Safikhani

Reputation: 945

useEffect will re-run the effect callback whenever any of the items in dependency array changes (e.g. loading goes from false to true).

The warning you are receiving is because you have used buttonValue in your effect callback but not included in the dependency array. So when you call the setButton() in click handler of the button, nothing happens because the useEffect won't detect any change to re-run the effect callback.

However, I suggest that you change the implementation, useEffect should be used for Side Effects (e.g. triggering a list update when the user selects a dropdown), not the effect themselves (Clicking on a submit buttons).

I would rewrite the code like this:

  const [value, setValue] = useState([]);
  const [isLoading, setLoading] = useState(false);

  useEffect(() => {
    axios.get('http://localhost:5000/').then(res => setValue(res.data))
  }, [])


  const handleCreateClick = () => {
      setLoading(true);
      axios.post('http://localhost:5000/create').then(() => {
        setLoading(false);
      });
  }

  const handleDeleteClick = () => {
      setLoading(true);
      axios.delete('http://localhost:5000/delete').then(() => {
        setLoading(false);
      });
  }


  return (
        <Form>
          <Form.Group>
             <Button variant='success' className='button' onClick={handleCreateClick} id='create'>Create Sales Order</Button>
          </Form.Group>
          <Form.Group>
             <Button variant='danger' className='button' onClick={handleDeleteClick} id='delete'>Delete Sales Order</Button>
          </Form.Group>
        </Form>
  );

The approach above is more readable and less error-prone as we are separating the effects from side-effects.

Upvotes: 1

Related Questions