title: React custom hooks taking dynamic data properties
body: <p>So I've read these blog posts about using custom hooks to fetch data, so for instance we have a custom hook doing the API call, setting the data, possible errors as well as the spinny isFetching boolean:</p>
  <pre><code>export const useFetchTodos = () =&gt; {
      const [data, setData] = useState();
      const [isFetching, setIsFetching] = useState(false);
      const [error, setError] = useState();
      useEffect(() =&gt; {
        setIsFetching(true);
        axios.get('api/todos')
          .then(response =&gt; setData(response.data)
          .catch(error =&gt; setError(error.response.data)
          .finally(() =&gt; setFetching(false);
        }, []);
       return {data, isFetching, error};
  }
  </code></pre>
  <p>And then at the top level of our component we would just call <code>const { data, error, fetching } = useFetchTodos();</code> and all great we render our component with all the todos fetched.</p>
  <p>The thing I don't understand is how would we send dynamic data / parameters to the hook based on the internal state of the component, without breaking the rules of hooks?</p>
  <p>For instance, imagine we have a <code>useFetchTodoById(id)</code> hook defined the same way as the above one, how would we pass that <code>id</code> around? Let's say our <code>TodoList</code> component which renders our Todos is the following:</p>
  <pre><code>export const TodoList = (props) =&gt; {
      const [selectedTodo, setSelectedTodo] = useState();
      
      useEffect(() =&gt; {
        useFetchTodoById(selectedTodo.id) --&gt; INVALID HOOK CALL, cannot call custom hooks from useEffect, 
          and also need to call our custom hooks at the &quot;top level&quot; of our component
      }, [selectedTodo]);
  
      return (&lt;ul&gt;{props.todos.map(todo =&gt; (
              &lt;li onClick={() =&gt; setSelectedTodo(todo.id)}&gt;{todo.name}&lt;/li&gt;)}
          &lt;/ul&gt;);
  }
  </code></pre>
  <p>I know for this specific usecase we could pass our <code>selectedTodo</code> through props and call our <code>useFetchTodoById(props.selectedTodo.id)</code> at the top of our component, but I'm just illustrating the issue with this pattern I ran into, we won't always have the luxury of receiving the dynamic data that we need in the props.</p>
  <p>Also -- how would we apply this pattern for <code>POST/PUT/PATCH</code> requests which take dynamic data properties?</p>