Reactガイドを読んでいくその12

これは

Reactのガイドを読んでいく記事です。

ガイドのリンク

ja.reactjs.org

フォーム

フォーム2日目。

textarea タグ

HTMLでのtextareaは以下のように子要素にテキストを持つ。

<textarea>
  Hello there, this is some text in a text area
</textarea>

ReactではValueを指定する

class EssayForm extends React.Component {
  constructor(props) {
    super(props);
    // ここ
    this.state = {
      value: 'Please write an essay about your favorite DOM element.'
    };

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

select タグ

HTMLの場合selectタグはドロップダウンリストを作る。

<select>
  <option value="grapefruit">Grapefruit</option>
  <option value="lime">Lime</option>
  <option selected value="coconut">Coconut</option>
  <option value="mango">Mango</option>
</select>

Reactではちょっと複雑になっていますが、やりたいことは同じ。
valueを使う仕組みなのは他と変わらず。

class FlavorForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: 'coconut'};

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

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

  handleSubmit(event) {
    alert('Your favorite flavor is: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Pick your favorite flavor:
          <select value={this.state.value} onChange={this.handleChange}>
            <option value="grapefruit">Grapefruit</option>
            <option value="lime">Lime</option>
            <option value="coconut">Coconut</option>
            <option value="mango">Mango</option>
          </select>
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

file input タグ

HTMLでは、<input type="file"> でユーザーにファイルを選択させる機能がある。
Reactではこれは非制御コンポーネントになり、ここでは割愛されている。

複数の入力の処理

複数の入力をしたい場合は、それぞれにnameを用意することで解決することが可能。

class Reservation extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isGoing: true,
      numberOfGuests: 2
    };

    this.handleInputChange = this.handleInputChange.bind(this);
  }

  handleInputChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;

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

  render() {
    return (
      <form>
        <label>
          Is going:
          <input
            name="isGoing"
            type="checkbox"
            checked={this.state.isGoing}
            onChange={this.handleInputChange} />
        </label>
        <br />
        <label>
          Number of guests:
          <input
            name="numberOfGuests"
            type="number"
            value={this.state.numberOfGuests}
            onChange={this.handleInputChange} />
        </label>
      </form>
    );
  }
}

制御された入力における null 値

制御されたコンポーネントvalue プロパティに値を指定することで、変更させたくない場合にユーザーが値を変更できないようになる。
設定しているにも関わらず、変更できてしまうような場合はundefinedやnullが設定されてしまっていることが原因。

ReactDOM.render(<input value="hi" />, mountNode);
// しばらくすると編集可能になる
setTimeout(function() {
  ReactDOM.render(<input value={null} />, mountNode);
}, 1000);

制御されたコンポーネントの代替手段

制御されたコンポーネントは、あらゆる種類のデータの変更に対してイベントハンドラを書き、あらゆる入力状態を React コンポーネントに通してやる必要があるため、時としてうんざりすることがあります。

確かに。
既存のものをReactに変換していくのとかすごく苦労しそう。
そういう場合は非制御コンポーネントを使えってことらしい。
ADVANCEの内容なので随分先になりそうだけど覚えておこう。
ja.reactjs.org

本格的なソリューション

Formikを使うと便利らしい。

jaredpalmer.com

Redux-Formより優れている点がまとめられている。 qiita.com

Redux-Formよくわからないのでそっちはそっちで知らないと良し悪しがよくわからなかった。

今日はここまで。