如何使 useEffect 仅在单个依赖项更改时重新运行?

huangapple go评论76阅读模式
英文:

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:

如何使 useEffect 仅在单个依赖项更改时重新运行?...........................
如何使 useEffect 仅在单个依赖项更改时重新运行?

I want the onChange handler passed to it to fire only when the 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?

英文:

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

如何使 useEffect 仅在单个依赖项更改时重新运行?...........................
如何使 useEffect 仅在单个依赖项更改时重新运行?

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(() =&gt; {
      if (!editMode) { // only on submit
        onChange(value) // &quot;value&quot; is a state of my component
      }
    }, [editMode])

    return (
     &lt;div className=&#39;my-input&#39;&gt;
      &lt;input value={value} onChange={({target}) =&gt; setValue(target.value)}/&gt;
      &lt;Icon 
        name={editMode ? &#39;tick&#39; : &#39;pencil&#39;}
        onClick={() =&gt; setEditMode(editMode =&gt; !editMode)}
      /&gt;
     &lt;/div&gt;
    )

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?

答案1

得分: 3

以下是翻译好的部分:

"你现在看到的警告是因为你的 useEffect 函数不依赖于按键操作,而是依赖于 onChangevalue 的值。更好的做法可能是在 onChange 处理程序内部发送事件本身:

const onClick = React.useCallback(() => {
  const nextEditMode = !editMode
  setEditMode(nextEditMode)
  // 如果我们要切换到编辑模式,请触发事件。
  if (nextEditMode) {
    onChange(value)
  }
}, [value, onChange])

在这种情况下,当你这样做时,不需要使用 useEffect,因为只有在需要将操作表示为副作用时才应使用它,但在这种情况下并不需要;可以在事件处理程序中处理,这样做更容易阅读。"

英文:

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(() =&gt; {
  const nextEditMode = !editMode
  setEditMode(nextEditMode)
  // If we&#39;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.

huangapple
  • 本文由 发表于 2020年1月3日 23:28:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/59581188.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定