React Hooks での form の扱い方

## Hooks 出る前 (v16.7 まで)

`[key]: value` という書き方 (ES2015以降) で、setState することで、input ごとに onChange のメソッドを作らなくてすんでた。

```jsx
class InputForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: '',
      pass: '',
    };

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({ [event.target.name]: event.target.value });
  }

  handleSubmit(event) {
    event.preventDefault();
    console.log(this.state);
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" name="name" value={this.state.name} onChange={this.handleChange} />
        </label>
        <label>
          Pass:
          <input type="password" name="pass" value={this.state.pass} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}
```


## Hooks だと

👆のような書き方ができなくなってしまった。
無理に汎用的な関数を用意しないで、構文のように onChange に直接関数を書くほうが楽かもしれない。

```js
onChange={ (e) => { setName(e.target.value) }}
```

1つにまとめたかったら、case などでまとめることになると思われる。
(useState とか使ってだいぶスッキリした)

```jsx
const InputForm = () => {
  const [name, setName] = useState("");
  const [pass, setPass] = useState("");

  const handleChange = (event) => {
    switch (event.target.name) {
      case 'name':
        setName(event.target.value);
        break;
      case 'pass':
        setPass(event.target.value);
        break;
      default:
        console.log('key not found');
    }
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    console.log(name);
    console.log(pass);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input type="text" name="name" value={name} onChange={handleChange} />
      </label>
      <label>
        Pass:
        <input type="password" name="pass" value={pass} onChange={handleChange} />
      </label>
      <input type="submit" value="Submit" />
    </form>
  );
```


## Custom Hooks を使うと

👇のような書き方でかけるようになるっぽい。
なるほどなぁ〜。独自のHooks便利。　

```jsx
const InputForm = () => {
  const useInput = initialValue => {
    const [value, set] = useState(initialValue)
    return { value, onChange: (e) => set(e.target.value) }
  };

  const name = useInput("");
  const pass = useInput("");

  const handleSubmit = (event) => {
    event.preventDefault();
    console.log(name);
    console.log(pass);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input type="text" {...name} />
      </label>
      <label>
        Pass:
        <input type="password" {...pass} />
      </label>
      <input type="submit" value="Submit" />
    </form>
  );
}
```

## 追記

Hooks でも、state をまとめれば、[Hooks 出る前 (v16.7 まで)](#Hooks-出る前-(v16.7-まで)) でやっていたような書き方できることに気づいた。

```js
const InputForm = () => {
  const [state, setState] = useState({
    name: "",
    pass: ""
  });

  const handleChange = event => {
    setState({ ...state, [event.target.name]: event.target.value });
  };

  const handleSubmit = event => {
    event.preventDefault();
    console.log(state.name);
    console.log(state.pass);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input
          type="text"
          name="name"
          value={state.name}
          onChange={handleChange}
        />
      </label>
      <label>
        Pass:
        <input
          type="password"
          name="pass"
          value={state.pass}
          onChange={handleChange}
        />
      </label>
      <input type="submit" value="Submit" />
    </form>
  );
};
```


## REF

[React Custom Hooksのサンプル集 - Qiita](https://qiita.com/takeyuichi/items/41776005061f1697d67d#custom-hooks%E3%81%A8%E3%81%AF)