javascript – React: useEffect “paradox” with eventHandler props


Problem with this example.

I’ve got an Input component. This input component has an onChange prop to handle any data changes from inside.

As it should be, if I update the value from outside, the onChange prop is not fired, since nothing changed from inside the input component. If you start typing the onChange prop is fired and I can update the state from outside as well.

But if some condition is met (in my example just a boolean state), I want to prefill the input field from inside, therefore I’ll have to call an onChange event so that the App can update the state from outside.

The problem/paradox is that the useEffect checking for a condition now needs the onChange prop as a dependency, and since this prop is a method, it will change on every render. This means now the input element always resets to the value from the useEffect when anything is changed because the useEffect is triggered again.

My problem would not be there if I was allowed to remove the onChange prop from the useEffect dependency, but this is of course against the rules of the useEffect hook.

The only “solutions” that came to my mind:

  • I could move the condition outside of the Input element into the App component. This makes sense for my example, but in the actual scenario the should be the same every time the component is used, and I don’t want to repeat the condition every time from outside since the condition is also not just a boolean in the real scenario of course.
  • I could add an additional state, whether the condition has already be checked and fire the useEffect only if it has not been triggered yet. But this get really complicated really fast, if the condition needs to get checked again at some point, etc. etc.

I’ve come across this problem in different shapes scenarios, so I really hope to get an answer that can be applied to similar scenarios in general. Maybe I just have an anti-pattern in my code of how I work with event handlers?

Thank you in advance for all answers ^^.