title: UseEffect and useCallback still causes infinite loop in react project
body: <p>I can't seem to resolve an infinite loop issue in my react project.</p>
  
  <p>I'm working on a daily-log react app. Let me explain the project briefly. Here is the picture of the code for quick view:</p>
  
  <p><img src="https://i.stack.imgur.com/WEFfr.png" alt="Here is the picture of the code for quick view"></p>
  
  <p>The same code is available at the bottom.</p>
  
  <p><strong>The structure</strong> (from top to bottom)</p>
  
  <ol>
  <li>The <code>DailyLog</code> component has a form that uses <code>Question</code> components into which props are passed.</li>
  <li>The <code>Question</code> component uses the props to display a question and description. It also contains an <code>Input</code> component into which props are further passed down.</li>
  <li>The <code>Input</code> component takes the props and renders the appropriate form input field.</li>
  </ol>
  
  <p><strong>The logic</strong> (from bottom to top)</p>
  
  <ol>
  <li>The <code>Input</code> component handles it's own <code>inputState</code>.  The state is changed when the user inputs something and the <code>onChangeHandler</code> is triggered.</li>
  <li>The <code>Input</code> component also has a <code>useEffect()</code> hook that calls an <code>onInput()</code> function that was passed down as props from <code>DailyLog</code>.</li>
  <li>The <code>onInputHandler()</code> in the <code>DailyLog</code> component updates the <code>formState</code> which is the form-wide state containing all input field values. The <code>formState</code> is amended depending on which input field is filled at the time.</li>
  <li>The <code>onInputHandler()</code> uses the <code>useCallback()</code> hook which is supposed to stop an infinite loop caused by any parent/child re-renders. But it doesn't work :frowning: </li>
  </ol>
  
  <p>What's wrong in the code? What am I missing here? Code provided below:</p>
  
  <pre><code>//DailyLog.js
  import React, { useState, useCallback } from 'react';
  
  import Question from '../components/FormElements/Question';
  import questionData from '../components/DailyLog/questionData';
  import './DailyLog.css';
  
  const DailyLog = () =&gt; {
      const [formState, setFormState] = useState();
  
      const onInputHandler = useCallback(
          (inputId, inputValue) =&gt; {
              setFormState({
                  ...formState,
                  [inputId]: inputValue,
              });
          },
          [formState]
      );
  
      return (
          &lt;main className="container"&gt;
              &lt;form action="" className="form"&gt;
                  &lt;Question
                      id="title"
                      element="input"
                      type="text"
                      placeholder="Day, date, calendar scheme"
                      onInput={onInputHandler}
                  /&gt;
  
                  &lt;Question
                      id="focus"
                      question={questionData.focusQuestion}
                      description={questionData.focusDescription}
                      element="textarea"
                      placeholder="This month's focus is... This week's focus is..."
                      onInput={onInputHandler}
                  /&gt;
              &lt;/form&gt;
          &lt;/main&gt;
      );
  };
  
  export default DailyLog;
  
  </code></pre>
  
  <pre><code>//Question.js
  import React from 'react';
  
  import Input from './Input';
  import './Question.css';
  
  const Question = props =&gt; {
      return (
          &lt;div className="form__group"&gt;
              {props.question &amp;&amp; (
                  &lt;label className="form__label"&gt;
                      &lt;h2&gt;{props.question}&lt;/h2&gt;
                  &lt;/label&gt;
              )}
  
              &lt;small className="form__description"&gt;{props.description}&lt;/small&gt;
  
              &lt;Input
                  id={props.id}
                  element={props.element}
                  type={props.type}
                  placeholder={props.placeholder}
                  onInput={props.onInput}
              /&gt;
          &lt;/div&gt;
      );
  };
  
  export default Question;
  
  </code></pre>
  
  <pre><code>//Input.js
  import React, { useState, useEffect } from 'react';
  
  import './Input.css';
  
  const Input = props =&gt; {
      const [inputState, setInputState] = useState();
  
      const { id, onInput } = props;
  
      useEffect(() =&gt; {
          onInput(id, inputState);
      }, [id, onInput, inputState]);
  
      const onChangeHandler = event =&gt; {
          setInputState(event.target.value);
      };
  
      // check if question element type is for input or textarea
      const element =
          props.element === 'input' ? (
              &lt;input
                  id={props.id}
                  className="form__field"
                  type={props.type}
                  value={inputState}
                  placeholder={props.placeholder}
                  onChange={onChangeHandler}
              /&gt;
          ) : (
              &lt;textarea
                  id={props.id}
                  className="form__field"
                  rows="1"
                  value={inputState}
                  placeholder={props.placeholder}
                  onChange={onChangeHandler}
              /&gt;
          );
  
      return &lt;&gt;{element}&lt;/&gt;;
  };
  
  export default Input;
  
  </code></pre>