反応中の制御対無制御成分


ユーザ入力を処理した場合には、次の警告が出ているかもしれません.A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component.このチュートリアルでは、なぜこの警告が発生し、どのように解決するかを学びます.
次のコンポーネントを考えます.
import { useState } from "react"

function App() {
  const [email, setEmail] = useState()
  return (
    <div className="App">
      <label htmlFor="email">Email:</label>
      <input
        type="text"
        name="email"
        id="email"
        value={email}
        onChange={e => setEmail(e.target.value)}
      />
    </div>
  )
}

export default App
アプリケーションで上記のコードを実行し、入力に何かを入力し、ブラウザコンソールを開くと、同じ警告が表示されます.

一見したところ、ここで何が問題であるかを理解することができないかもしれませんが、観察したならば、私たちは任意の値なしでUSENTを使用して電子メールを初期化していることがわかります.
状態が値を渡さずに初期化されるとき、それはundefinedです.それで、ユーザーが何かをタイプするとき、onChangeハンドラーは引き起こされます.そして、それは定義された何かに電子メールの価値を設定します.
要するに、電子メールの値が未定義であるとき、それは制御されていない入力でした、そして、ユーザーが何かをタイプしたとき、onChangeハンドラーがメールの価値を更新した時から、それは制御された入力になりました.
反応は制御されていないと制御の間の入力を切り替えることをお勧めしません.

制御入力
まず、上記の例をどのように制御できるかを見てみましょう.
初期値として空の文字列をuseStateフックに渡すだけで、上記のコンポーネントを変換できます.
import { useState } from "react"

function App() {
  const [email, setEmail] = useState("")
  return (
    <div className="App">
      <label htmlFor="email">Email:</label>
      <input
        type="text"
        name="email"
        id="email"
        value={email}
        onChange={e => setEmail(e.target.value)}
      />
    </div>
  )
}

export default App
今、あなたが入力で何かをリフレッシュして、タイプするならば、あなたは警告が消えたのを見ます.

制御できない入力
あなたが見たように、制御された入力では、入力の現在の値を格納するためにいくつかの状態機械(local/global)を使用します.
制御されていない入力の場合、入力フィールドの値はDOM自体に格納される.入力への参照を渡し、リファレンスを使用して入力の値にアクセスします.
例の助けを借りてこれを見ましょう.
import React, { useRef } from "react"

const UncontrolledComponent = () => {
  const inputRef = useRef()
  const formSubmitHandler = e => {
    e.preventDefault()
    alert("Email: " + inputRef.current.value)
  }
  return (
    <div className="App">
      <form onSubmit={formSubmitHandler}>
        <label htmlFor="email">Email:</label>
        <input type="text" name="email" id="email" ref={inputRef} />
        <input type="submit" value="Submit" />
      </form>
    </div>
  )
}

export default UncontrolledComponent
上の例では
  • 私たちはuseRefフックを使って参照を宣言して、それを電子メール入力に渡します.
  • フォームが送信されると、inputRef.current.valueを使用してアクセスできます
  • 我々は、任意の時点でユーザーによって入力値を制御していません.

  • 制御されていない入力に対する制御入力の利点
    既に見たように.
  • 我々は入力を制御する入力を囲む形式を必要としない.
  • 制御入力の
  • は、各変更後の入力値にアクセスできるので、ユーザーが文字を入力するたびに入力検証を行うことができます.コントロールされていない入力の場合、ユーザーがフォームを送信するときにのみ検証を実行できます.
  • 次の例では、制御コンポーネントの妥当性検査部分を見てみましょう.
    import { useState } from "react"
    
    function App() {
      const [email, setEmail] = useState("")
      const [error, setError] = useState("")
    
      const inputChangeHandler = e => {
        const value = e.target.value
        setEmail(e.target.value)
        if (
          !/[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/i.test(
            value
          )
        ) {
          setError("Invalid Email")
        } else {
          setError("")
        }
      }
      return (
        <div className="App">
          <div className="form-control">
            <label htmlFor="email">Email:</label>
            <input
              type="text"
              name="email"
              id="email"
              value={email}
              onChange={inputChangeHandler}
            />
            <p className="error">{error && error}</p>
          </div>
        </div>
      )
    }
    
    export default App
    
    ユーザーが文字を入力するたびに、正しいメールであるかどうかを検証し、エラーメッセージが表示されます.
    アプリを実行する前に、いくつかのスタイルをindex.cssに追加しましょう.
    body {
      margin: 20px auto;
      text-align: center;
    }
    input,
    label {
      margin-right: 5px;
    }
    
    .error {
      margin: 5px 0;
      color: red;
    }
    
    今すぐアプリを実行し、不正なメールを入力すると、エラーが表示されることができるはずです.

    You can learn more about form validation in react in one of my previous posts.



    ソースコード
    あなたはsource code hereをダウンロードすることができます.