<p dir="auto"><em>Versions:</em></p>
<ul dir="auto">
<li><strong>react</strong>: 16.8.0-alpha-0</li>
<li><strong>react-dom</strong>: 16.8.0-alpha-0</li>
<li><strong>react-form-uncontrolled</strong>: 0.3.1</li>
</ul>
<h3 dir="auto">Problem</h3>
<p dir="auto">I wrote a simple Form library with just one hook (react-form-uncontrolled). However, <strong>using this library</strong> is displaying this error:</p>
<blockquote>
<p dir="auto">Invariant Violation: Hooks can only be called inside the body of a function component</p>
</blockquote>
<p dir="auto">Codesandbox: <a href="https://codesandbox.io/s/znx2r55lkp" rel="nofollow">https://codesandbox.io/s/znx2r55lkp</a></p>
<p dir="auto">Although the error says that it can only be called inside the body of a function component, is already on the body...</p>
<p dir="auto">Original library code:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import React, { useCallback } from 'react'

function Form(props) {
  const onSubmitForm = useCallback(event =&gt; {
    event.preventDefault()
    event.stopPropagation()

    const { onSubmit = () =&gt; {} } = props
    const fields = Array.prototype.slice.call(event.target)
      .filter(field =&gt; field.name)
      .reduce((form, { name, value }) =&gt; ({
        ...form,
        [name]: typeof value === 'string'
          ? value.trim()
          : value,
      }), {})

    onSubmit(fields)
  }, [])
  const { children } = props

  return (
    &lt;form {...props} onSubmit={onSubmitForm}&gt;
      {children}
    &lt;/form&gt;
  )
}

function Input(props) {
  const { label, name } = props

  return (
    &lt;label htmlFor={name}&gt;
      &lt;div&gt;{label}&lt;/div&gt;
      &lt;input
        {...props}
        id={name}
        name={name}
      /&gt;
    &lt;/label&gt;
  )
}

module.exports = {
  Form, Input,
}"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-v">React</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-s1">useCallback</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'react'</span>

<span class="pl-k">function</span> <span class="pl-v">Form</span><span class="pl-kos">(</span><span class="pl-s1">props</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-k">const</span> <span class="pl-s1">onSubmitForm</span> <span class="pl-c1">=</span> <span class="pl-en">useCallback</span><span class="pl-kos">(</span><span class="pl-s1">event</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-s1">event</span><span class="pl-kos">.</span><span class="pl-en">preventDefault</span><span class="pl-kos">(</span><span class="pl-kos">)</span>
    <span class="pl-s1">event</span><span class="pl-kos">.</span><span class="pl-en">stopPropagation</span><span class="pl-kos">(</span><span class="pl-kos">)</span>

    <span class="pl-k">const</span> <span class="pl-kos">{</span> onSubmit <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span><span class="pl-kos">}</span> <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-s1">props</span>
    <span class="pl-k">const</span> <span class="pl-s1">fields</span> <span class="pl-c1">=</span> <span class="pl-v">Array</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span><span class="pl-kos">.</span><span class="pl-c1">slice</span><span class="pl-kos">.</span><span class="pl-en">call</span><span class="pl-kos">(</span><span class="pl-s1">event</span><span class="pl-kos">.</span><span class="pl-c1">target</span><span class="pl-kos">)</span>
      <span class="pl-kos">.</span><span class="pl-en">filter</span><span class="pl-kos">(</span><span class="pl-s1">field</span> <span class="pl-c1">=&gt;</span> <span class="pl-s1">field</span><span class="pl-kos">.</span><span class="pl-c1">name</span><span class="pl-kos">)</span>
      <span class="pl-kos">.</span><span class="pl-en">reduce</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">form</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> name<span class="pl-kos">,</span> value <span class="pl-kos">}</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">(</span><span class="pl-kos">{</span>
        ...<span class="pl-s1">form</span><span class="pl-kos">,</span>
        <span class="pl-kos">[</span><span class="pl-s1">name</span><span class="pl-kos">]</span>: <span class="pl-k">typeof</span> <span class="pl-s1">value</span> <span class="pl-c1">===</span> <span class="pl-s">'string'</span>
          ? <span class="pl-s1">value</span><span class="pl-kos">.</span><span class="pl-en">trim</span><span class="pl-kos">(</span><span class="pl-kos">)</span>
          : <span class="pl-s1">value</span><span class="pl-kos">,</span>
      <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">)</span>

    <span class="pl-en">onSubmit</span><span class="pl-kos">(</span><span class="pl-s1">fields</span><span class="pl-kos">)</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">)</span>
  <span class="pl-k">const</span> <span class="pl-kos">{</span> children <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-s1">props</span>

  <span class="pl-k">return</span> <span class="pl-kos">(</span>
    <span class="pl-c1">&lt;</span><span class="pl-ent">form</span> <span class="pl-kos">{</span>...<span class="pl-s1">props</span><span class="pl-kos">}</span> <span class="pl-c1">onSubmit</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-s1">onSubmitForm</span><span class="pl-kos">}</span><span class="pl-c1">&gt;</span>
      <span class="pl-kos">{</span><span class="pl-s1">children</span><span class="pl-kos">}</span>
    <span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">form</span><span class="pl-c1">&gt;</span>
  <span class="pl-kos">)</span>
<span class="pl-kos">}</span>

<span class="pl-k">function</span> <span class="pl-v">Input</span><span class="pl-kos">(</span><span class="pl-s1">props</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-k">const</span> <span class="pl-kos">{</span> label<span class="pl-kos">,</span> name <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-s1">props</span>

  <span class="pl-k">return</span> <span class="pl-kos">(</span>
    <span class="pl-c1">&lt;</span><span class="pl-ent">label</span> <span class="pl-c1">htmlFor</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-s1">name</span><span class="pl-kos">}</span><span class="pl-c1">&gt;</span>
      <span class="pl-c1">&lt;</span><span class="pl-ent">div</span><span class="pl-c1">&gt;</span><span class="pl-kos">{</span><span class="pl-s1">label</span><span class="pl-kos">}</span><span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">div</span><span class="pl-c1">&gt;</span>
      <span class="pl-c1">&lt;</span><span class="pl-ent">input</span>
        <span class="pl-kos">{</span>...<span class="pl-s1">props</span><span class="pl-kos">}</span>
        <span class="pl-c1">id</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-s1">name</span><span class="pl-kos">}</span>
        <span class="pl-c1">name</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-s1">name</span><span class="pl-kos">}</span>
      <span class="pl-c1">/</span><span class="pl-c1">&gt;</span>
    <span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">label</span><span class="pl-c1">&gt;</span>
  <span class="pl-kos">)</span>
<span class="pl-kos">}</span>

<span class="pl-smi">module</span><span class="pl-kos">.</span><span class="pl-c1">exports</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
  Form<span class="pl-kos">,</span> Input<span class="pl-kos">,</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">At the beginning I thought that was for the Babel transpilation. Nevertheless, running a codesandbox using the transpiled code instead of the library, is working well:</p>
<ul dir="auto">
<li><a href="https://codesandbox.io/s/k0j6zn2xzo" rel="nofollow">https://codesandbox.io/s/k0j6zn2xzo</a></li>
</ul>
<p dir="auto">Downgrading these versions in the project that use the library, it works:</p>
<ul dir="auto">
<li><strong>react</strong> -&gt; from 16.8.0-alpha.0 -&gt; to 16.7.0-alpha.2</li>
<li><strong>react-dom:</strong> from 16.8.0-alpha.0 -&gt; to 16.7.0-alpha.2</li>
</ul>
<p dir="auto">So looks that for some reason with 16.8.0-alpha.0 is not compatible.</p>
<blockquote>
<p dir="auto"><strong>Note</strong>: Perhaps is not an issue and is something that I'm doing wrong... Any sugestion?</p>
</blockquote>
<p dir="auto"><a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/gaearon/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/gaearon">@gaearon</a> I normally bundle React and all its add-ons in a different file from my application, but when using ReactPerf I forgot of including it in the same bundle of React and ReactDOM, so I noticed I was receiving an empty array from ReactPerf functions every time I was using them, and that is because ReactDebugTool is different for the application and for React which means flushHistory is also different.</p>
<p dir="auto">What do you think about warning the user if there are more than one instance of ReactPerf/ReactDebugTool in the page?</p>