UtkarshPramodGupta
UtkarshPramodGupta

Reputation: 8152

How to make useEffect rerun only on change of a single dependency?

I have created a custom input component that has an attached 'edit/submit' button, like so:

enter image description here........................... enter image description here

I want the onChange handler passed to it to fire only when user hits the submit button i.e. (✓) and not on every keypress. So, in useEffect I did:

    useEffect(() => {
      if (!editMode) { // only on submit
        onChange(value) // "value" is a state of my component
      }
    }, [editMode])

    return (
     <div className='my-input'>
      <input value={value} onChange={({target}) => setValue(target.value)}/>
      <Icon 
        name={editMode ? 'tick' : 'pencil'}
        onClick={() => setEditMode(editMode => !editMode)}
      />
     </div>
    )

But the linter starts to bang:

useEffect has missing dependencies: 'onChange' and 'value'...

How to fix this issue or am I using an incorrect hook here?

Upvotes: 1

Views: 2424

Answers (1)

Dan
Dan

Reputation: 10538

The warning you're seeing is because your useEffect function doesn't depend on a key press, it depends on the value of onChange and value. A better way to accomplish this might be to send the event inside of the onChange handler itself:

const onClick = React.useCallback(() => {
  const nextEditMode = !editMode
  setEditMode(nextEditMode)
  // If we're flipping editMode on, fire the event.
  if (nextEditMode) {
    onChange(value)
  }
}, [value, onChange])

useEffect should be used when you can only represent the thing you want as a side-effect, but there's no need to do that in this case; this can handled in event handler, and it is easier to read when you do so.

Upvotes: 3

Related Questions