React

【JavaScript】6桁のコードを6つのinputに分けて入力するヤツ【React】

React
この記事は約4分で読めます。

株式会社インプルの平澤です。
認証コードの入力などで稀に目にする「6桁のコードでinputが6つに分かれている」やつをご紹介します。
見た目がスタイリッシュで個人開発しているとどうしても入れたくなりますよね。(?)
実装にはReactを使用してます。(TypeScriptも使用してますがほとんどanyなので恩恵ありません

挙動としては、
・ページ表示時に1桁目にフォーカスされる
・入力すると次のinputにフォーカスされる
・2桁目以降で未入力の場合にバックスペース押下で前のinputを削除しフォーカス
と言った感じです。(詳しくは下記の動画をご覧ください)

下記コードですが、スタイルはTailwind CSSを使用してます。
Tailwindについては下記ページを参照ください。
https://ramble.impl.co.jp/1414/
ではコードをどうぞ。

import React, { useState, useRef, useEffect } from "react"

export default () => {
  const [code, setCode] = useState<string[]>(["", "", "", "", "", ""])
  const [inputIndex, setIndex] = useState(0)

  const inputRef: any = [
    useRef(null),
    useRef(null),
    useRef(null),
    useRef(null),
    useRef(null),
    useRef(null),
  ]

  const bsFunction = (event: any) => {
    if (event.key === "Backspace" && inputIndex > 0) {
      inputRef[inputIndex - 1].current.focus()
      setIndex(inputIndex - 1)
    }
  }

  useEffect(() => {
    document.addEventListener("keydown", bsFunction, false)
    return () => {
      document.removeEventListener("keydown", bsFunction, false)
    }
  }, [bsFunction])

  return(
    <div className="flex items-center justify-around">
      {[...Array(6)].map((_, i) => (
        <input
          className="w-[12%] text-[50px] text-center h-[100px] border-0 bg-gray-100 rounded-md"
          maxLength={1}
          key={i}
          autoFocus={i === 0}
          value={code[i]}
          type="tel"
          ref={inputRef[i]}
          onChange={(e) => {
            const codeArray = [
              i !== 0 ? code[0] : e.target.value,
              i !== 1 ? code[1] : e.target.value,
              i !== 2 ? code[2] : e.target.value,
              i !== 3 ? code[3] : e.target.value,
              i !== 4 ? code[4] : e.target.value,
              i !== 5 ? code[5] : e.target.value,
            ]
            setCode([...codeArray])
            if (e.target.value !== "") {
              i < 5 && inputRef[i + 1].current.focus()
              setIndex(inputIndex + 1)
            }
          }}
        />
      ))}
    </div>
  )
}

詳しい解説は省きます!
コピペしてカスタマイズしてぜひお試しくださいませ。

これであなたもrefマスター!!!!! (?)