title: How to rewrite a React class that extends another class as a functional component?
body: <p>I have the following simple code and I am trying to rewrite it as a function avoiding classes and using hooks for learning purposes.
  As you can see below, 'App' is extending 'Form'. The complete code includes other functions in 'Form', for example, a validation function which is called by 'handleChange' and modifies the 'errors' item in the state. 
  Note that 'Form' is not part of 'App' because Form will be reused by other components (such as a login component).</p>
  
  <p>My main questions:</p>
  
  <p>1- As per the <a href="https://reactjs.org/docs/composition-vs-inheritance.html" rel="nofollow noreferrer">documentation</a>, they seem to discourage the use of Inheritance, how can I rewrite this without using "extends" (and keeping the classes)?</p>
  
  <p><strong>2- How can I rewrite this without classes?</strong></p>
  
  <p>So far, the only idea that came to my mind is to rewrite all the functions in form.jsx as independent functions and call them from App (see below). But this implies to write a lot of props and parameters (specially when validation is added as 'errors', 'setErrors', 'schema', etc. would be sent from 'App' to 'renderInput', from here to 'handleChange', etc.
  It works but the code is less clean than before...</p>
  
  <p>app.js</p>
  
  <pre><code>class App extends Form {
    state = {
      data: { username: "", password: "" },
    };
  
    render() {
      return (
        &lt;form action=""&gt;
          {this.renderInput("username", "Username")}
          {this.renderInput("password", "Password", "password")}
        &lt;/form&gt;
      );
    }
  }
  </code></pre>
  
  <p>form.jsx</p>
  
  <pre><code>class Form extends Component {
    state = {
      data: {},
    };
  
    handleChange = ({ currentTarget }) =&gt; {
      const data = { ...this.state.data };
      data[currentTarget.name] = currentTarget.value;
      this.setState({ data });
    };
  
    renderInput(name, label, type = "text") {
      const { data, errors } = this.state;
  
      return (
        &lt;Input
          name={name}
          type={type}
          value={data[name]}
          label={label}
          onChange={this.handleChange}
        /&gt;
      );
    }
  
    render() {
      return null;
    }
  }
  
  export default Form;
  </code></pre>
  
  <p>input.jsx</p>
  
  <pre><code>const Input = ({ name, label, ...rest }) =&gt; {
    return (
      &lt;div className="form-group"&gt;
        &lt;label htmlFor={name}&gt;{label}&lt;/label&gt;
        &lt;input {...rest} name={name} id={name} className="form-control" /&gt;
      &lt;/div&gt;
    );
  };
  </code></pre>
  
  <p>Attempt to change it into functions:</p>
  
  <p>App.jsx</p>
  
  <pre><code>const App = () =&gt; {
    const [user, setUser] = useState({ username: "", password: "" });
  
    return (
      &lt;form action=""&gt;
        {renderInput("username", "Username", user, setUser)}
        {renderInput("password", "Password", user, setUser, "password")}
      &lt;/form&gt;
    );
  };
  </code></pre>
  
  <p>form.jsx</p>
  
  <pre><code>export function handleChange({ currentTarget }, data, setData) {
    setData({ ...data, [currentTarget.name]: currentTarget.value });
  }
  
  export function renderInput(name, label, data, setData, type = "text") {
    return (
      &lt;Input
        name={name}
        type={type}
        value={data[name]}
        label={label}
        onChange={e =&gt; handleChange(e, data, setData)}
      /&gt;
    );
  }
  </code></pre>
  
  <p>Thanks in advance and let me know if you need a better explanation or the full code.</p>