search
LoginSignup
6

More than 3 years have passed since last update.

posted at

updated at

Organization

入力直後に変換を入れる場合のUX

Controlledのメリット

ReactではControlled Componentといって、デフォルトで<input>などにデータは保存されず、onChangeイベントでデータを拾って回収する必要があります。

ただ、必ずしもこれは入力フォームのデータをそのまま保存する必要がない、ということでもあります。たとえば、内部で扱うデータは摂氏だけど、onChangeで華氏→摂氏に変換、valueで逆変換を行えば、データ構造に変化なくフォームだけ華氏に切り替えられます。

不可逆変換の、UX上の問題点

そのように、可逆な変換を行う分にはユーザーが気づく機会もなく、便利なだけなのですが、不可逆な変換を入れるととたんにややこしくなります。

たとえば、onChangeで数字をコンマ区切りにするような処理を入れた場合、「12,345」を入力するつもりであっても、「1234」まで入力したところで「1,234」となってしまい、なかなか気持ち悪いものとなります。

さらに、onChangeで特定の文字だけ削るような処理を入れると、その文字を入力した場合に何も反応しないような挙動となってしまいます。ユーザーの操作を「認識はしているけど表示上は何も変化しない」挙動を起こすと、ユーザーとしては「押していないんじゃないか」と不安をいだいたりして、ユーザー体験を損ねてしまいます。

対策

「入力を受け付ける」→「自動変換」というプロセスがわかりやすくなるようにするために、変換はonBlurまで遅らせてしまうのもいいでしょう。入力が終わってフォーカスを移せば、値が変換されます。Reactで再現するには、本来の値データ以外に「入力中の仮の値」を入れるためのデータ領域が必要となります。

class BlurChangingInput extends React.Component{
  state = {
    value: '',
    inputtingValue: null
  }

  // そのまま入力中の値を格納するだけ
  handleChange = e => {
    this.setState({inputtingValue: e.target.value});
  }

  // 値を変換(ハイフンを消す)
  // 入力中の値はクリア
  handleBlur = () => {
    const value = this.state.inputtingValue.replace(/-/g, '');
    this.setState({value, inputtingValue: null});
  }

  render() {
    const {inputtingValue, value} = this.state;
    const displayValue = inputtingValue == null ? value : inputtingValue;
    return(
      <input type="text"
        value={displayValue}
        onChange={this.handleChange}
        onBlur={this.handleBlur}
        placeholder="ハイフンは自動で消えます"
        className="form-control"
      />
    );
  }
}

なお、inputtingValue == nullとしていますが、空文字列も正当な値なので、inputtingValue || valueとした場合にはフォームを空にしようとした瞬間に元の値が復活する、という挙動になってしまいます。

CodePenに上げました

比較のために「その場でハイフンを消す」フォームと「blurで消す」フォームを作ってみました。動きをご自身でも試していただければと思います。

See the Pen xQWKBJ by Jkr2255 (@jkr2255) on CodePen.

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
6