רכיב הדפדפן המובנה <input> מאפשר לך להציג סוגים שונים של קלט טפסים.

<input />

הפניה

<input>

כדי להציג קלט, רנדר את הדפדפן המובנה <input> רכיב.

<input name="myInput" />

ראה דוגמאות נוספות למטה.

אבזרים

<input> תומך בכל הרכיב המשותף props.

Canary

ההרחבות של React לאביזר formAction זמינות כרגע רק בערוצים הקנריים והניסיוניים של React. במהדורות יציבות של React, formAction פועל רק כרכיב HTML דפדפן מובנה. למידע נוסף על ערוצי ההפצה של React כאן.

formAction: מחרוזת או פונקציה. עוקפת את האב <form action> עבור type="submit" וtype="image". כאשר כתובת URL מועברת ל-action הטופס יתנהג כמו טופס HTML סטנדרטי. כאשר פונקציה תועבר ל-formAction הפונקציה תטפל בטופס ההגשה. <form action>.

אתה יכול להפוך קלט מבוקר על ידי העברת אחד מה-props הבאים:

  • checked: בוליאני. עבור קלט תיבת סימון או לחצן בחירה, שולט אם הוא נבחר.
  • value: מחרוזת. עבור קלט טקסט, שולט בטקסט שלו. (עבור לחצן בחירה, מציין את נתוני הטופס שלו.)

כאשר אתה עובר אחד מהם, עליך לעבור גם מטפל onChange שמעדכן את הערך שעבר.

<input> props אלו רלוונטיים רק לכניסות לא מבוקרות:

<input> props אלו רלוונטיים הן לכניסות לא מבוקרות והן לכניסות מבוקרות:

  • accept: מחרוזת. מציין אילו סוגי קבצים מתקבלים על ידי קלט type="file".
  • alt: מחרוזת. מציין את טקסט התמונה החלופי עבור קלט type="image".
  • capture: מחרוזת. מציין את המדיה (מיקרופון, וידאו או מצלמה) שנלכדה על ידי קלט type="file".
  • autoComplete: מחרוזת. מציינת אחת מ[התנהגויות השלמה אוטומטית] האפשריות.](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete#values)
  • autoFocus: בוליאני. אם true, React ימקד את האלמנט ב-mount.
  • dirname: מחרוזת. מציין את שם שדה הטופס עבור הכיווניות של האלמנט.
  • disabled: בוליאני. אם true, הקלט לא יהיה אינטראקטיבי ויופיע מעומעם.
  • children: <input> אינו מקבל ילדים.
  • form: מחרוזת. מציין את id של <form> שהקלט הזה שייך אליו. אם מושמט, זה טופס האב הקרוב ביותר.
  • formAction: מחרוזת. עוקף את ההורה <form action> עבור type="submit" וtype="image".
  • formEnctype: מחרוזת. עוקף את ההורה <form enctype> עבור type="submit" וtype="image".
  • formMethod: מחרוזת. עוקף את ההורה <form method> עבור type="submit" וtype="image".
  • formNoValidate: מחרוזת. עוקף את ההורה <form noValidate> עבור type="submit" וtype="image".
  • formTarget: מחרוזת. עוקף את ההורה <form target> עבור type="submit" וtype="image".
  • height: מחרוזת. מציין את גובה התמונה עבור type="image".
  • list: מחרוזת. מציין את ה-id של ה-<datalist> עם אפשרויות ההשלמה האוטומטית.
  • max: מספר. מציין את הערך המרבי של קלט מספרי ותאריך-שעה.
  • maxLength: מספר. מציין את האורך המרבי של טקסט וקלטים אחרים.
  • min: מספר. מציין את הערך המינימלי של קלט מספרי ותאריך-שעה.
  • minLength: מספר. מציין את האורך המינימלי של טקסט וקלטים אחרים.
  • multiple: ערך בוליאני. מציין אם מותרים ערכים מרובים עבור <type="file" וtype="email".
  • name: מחרוזת. מציין את השם לקלט זה נשלח עם הטופס.
  • onChange: פונקציה Event מטפל. נדרש עבור כניסות מבוקרות. מופעל מיד כאשר ערך הקלט משתנה על ידי ה-user (לדוגמה, הוא מופעל בכל הקשה). מתנהג כמו הדפדפן input אירוע.
  • onChangeCapture: גרסה של onChange שנורה בשלב לכידה.
  • פונקציה onInput: מטפל Event. מופעלת מיד כאשר הערך משתנה על ידי ה-user. מסיבות היסטוריות, ב-TK_124_124, במקום זאת, TK_124_3 הוא TK_124_0 הוא K__13. עובד באופן דומה.
  • onInputCapture: גרסה של onInput שנורה בשלב לכידה.
  • פונקציה onInvalid: מטפל Event. מופעל אם קלט נכשל באימות בשליחת הטופס. בניגוד לאירוע המובנה invalid, האירוע React בועות React __3
  • onInvalidCapture: גרסה של onInvalid שנורה בשלב לכידה.
  • פונקציה onSelect: מטפל ב-Event. מופעל לאחר שהבחירה בתוך ה-<input> משתנה. React מרחיב את onSelect __ ויכול להשפיע על הבחירה הריקה שלו.
  • onSelectCapture: גרסה של onSelect שנורה בשלב לכידה.
  • pattern: מחרוזת. מציין את התבנית שה-value חייב להתאים.
  • placeholder: מחרוזת. מוצג בצבע מעומעם כאשר ערך הקלט ריק.
  • readOnly: בוליאני. אם true, הקלט אינו ניתן לעריכה על ידי ה-user.
  • required: בוליאני. אם true, יש לספק את הערך כדי שהטופס יישלח.
  • size: מספר. דומה להגדרת רוחב, אבל היחידה תלויה בבקרה.
  • src: מחרוזת. מציין את מקור התמונה עבור קלט type="image".
  • step: מספר חיובי או מחרוזת 'any'. מציין את המרחק בין ערכים חוקיים.
  • type: מחרוזת. אחד מסוגי הקלט.
  • width: מחרוזת. מציין את רוחב התמונה עבור קלט type="image".

אזהרות

  • תיבות סימון צריכות checked (או defaultChecked), לא value (או defaultValue).
  • אם קלט טקסט מקבל מחרוזת value אבזר, הוא יטופל כנשלט.](#controlling-an-input-with-a-state-variable)
  • אם תיבת סימון או כפתור בחירה מקבלים אבזר בוליאני checked, זה יטופל כנשלט.](#controlling-an-input-with-a-state-variable)
  • קלט לא יכול להיות נשלט ובלתי נשלט בו זמנית.
  • קלט לא יכול לעבור בין להיות נשלט או בלתי נשלט במהלך חייו.
  • כל קלט מבוקר צריך מטפל אירועים onChange שמעדכן באופן סינכרוני את ערך הגיבוי שלו.

שימוש

הצגת קלט מסוגים שונים

כדי להציג קלט, רנדר רכיב <input>. כברירת מחדל, זה יהיה קלט טקסט. אתה יכול להעביר את type="checkbox" עבור תיבת סימון, type="radio" עבור לחצן בחירה, או אחד מסוגי הקלט האחרים.

export default function MyForm() {
  return (
    <>
      <label>
        Text input: <input name="myInput" />
      </label>
      <hr />
      <label>
        Checkbox: <input type="checkbox" name="myCheckbox" />
      </label>
      <hr />
      <p>
        Radio buttons:
        <label>
          <input type="radio" name="myRadio" value="option1" />
          Option 1
        </label>
        <label>
          <input type="radio" name="myRadio" value="option2" />
          Option 2
        </label>
        <label>
          <input type="radio" name="myRadio" value="option3" />
          Option 3
        </label>
      </p>
    </>
  );
}


מתן תווית לקלט

בדרך כלל, תציב כל <input> בתוך תג <label>. זה אומר לדפדפן שהתווית הזו משויכת לקלט הזה. כאשר ה-user לוחץ על התווית, הדפדפן ימקד את הקלט באופן אוטומטי. זה גם חיוני לנגישות: קורא מסך יכריז על כיתוב התווית המשויך ל-K4__5__T__T

אם אינך יכול לקנן את <input> לתוך <label>, שייך אותם על ידי העברת אותו מזהה ל-<input id> ו-<label htmlFor>. כדי למנוע התנגשויות בין מופעים מרובים של רכיב אחד, צור מזהה כזה עם useId.

import { useId } from 'react';

export default function Form() {
  const ageInputId = useId();
  return (
    <>
      <label>
        Your first name:
        <input name="firstName" />
      </label>
      <hr />
      <label htmlFor={ageInputId}>Your age:</label>
      <input id={ageInputId} name="age" type="number" />
    </>
  );
}


מתן ערך התחלתי עבור קלט

ניתן לציין באופן אופציונלי את הערך ההתחלתי עבור כל קלט. העבר אותו כמחרוזת defaultValue עבור קלט טקסט. תיבות סימון ולחצני בחירה צריכים לציין את הערך ההתחלתי עם הערך הבוליאני defaultChecked במקום זאת.

export default function MyForm() {
  return (
    <>
      <label>
        Text input: <input name="myInput" defaultValue="Some initial value" />
      </label>
      <hr />
      <label>
        Checkbox: <input type="checkbox" name="myCheckbox" defaultChecked={true} />
      </label>
      <hr />
      <p>
        Radio buttons:
        <label>
          <input type="radio" name="myRadio" value="option1" />
          Option 1
        </label>
        <label>
          <input
            type="radio"
            name="myRadio"
            value="option2"
            defaultChecked={true} 
          />
          Option 2
        </label>
        <label>
          <input type="radio" name="myRadio" value="option3" />
          Option 3
        </label>
      </p>
    </>
  );
}


קריאת ערכי הקלט בעת שליחת טופס

הוסף <form> מסביב לכניסות שלך עם <button type="submit"> בפנים. זה יקרא למטפל האירועים <form onSubmit> שלך. כברירת מחדל, הדפדפן ישלח את נתוני הטופס לכתובת ה-URL הנוכחית וירענן את הדף. תוכל לעקוף התנהגות זו על ידי קריאה ל-new FormData(e.target)](__K__נתוני הטופס עם [__K_7).

export default function MyForm() {
  function handleSubmit(e) {
    // Prevent the browser from reloading the page
    e.preventDefault();

    // Read the form data
    const form = e.target;
    const formData = new FormData(form);

    // You can pass formData as a fetch body directly:
    fetch('/some-api', { method: form.method, body: formData });

    // Or you can work with it as a plain object:
    const formJson = Object.fromEntries(formData.entries());
    console.log(formJson);
  }

  return (
    <form method="post" onSubmit={handleSubmit}>
      <label>
        Text input: <input name="myInput" defaultValue="Some initial value" />
      </label>
      <hr />
      <label>
        Checkbox: <input type="checkbox" name="myCheckbox" defaultChecked={true} />
      </label>
      <hr />
      <p>
        Radio buttons:
        <label><input type="radio" name="myRadio" value="option1" /> Option 1</label>
        <label><input type="radio" name="myRadio" value="option2" defaultChecked={true} /> Option 2</label>
        <label><input type="radio" name="myRadio" value="option3" /> Option 3</label>
      </p>
      <hr />
      <button type="reset">Reset form</button>
      <button type="submit">Submit form</button>
    </form>
  );
}

Note

תן name לכל <input>, למשל <input name="firstName" defaultValue="Taylor" />. ה-name שציינת יהיה used כמפתח בנתוני הטופס, למשל { firstName: "Taylor" }.

Pitfall

כברירת מחדל, כל <button> בתוך <form> ישלח אותו. זה יכול להפתיע! אם יש לך רכיב Button React מותאם אישית משלך, שקול להחזיר <button type="button"> במקום <button>. לאחר מכן, כדי להיות מפורש, use <button type="submit"> עבור לחצנים שאמורים לשלוח את הטופס.


שליטה בקלט עם משתנה state

קלט כמו <input /> הוא לא מבוקר. גם אם אתה מעביר ערך התחלתי כמו <input defaultValue="Initial text" />, ה-JSX שלך מציין רק את הערך ההתחלתי. זה לא שולט מה הערך צריך להיות עכשיו.

כדי להציג קלט מבוקר, העבירו אליו את הפרופס value (או checked עבור תיבות סימון ומכשירי רדיו). React יאלץ את הקלט לכלול תמיד את ה-value שעברתם. בדרך כלל, תעשה זאת על ידי הכרזה על משתנה state:

function Form() {
const [firstName, setFirstName] = useState(''); // Declare a state variable...
// ...
return (
<input
value={firstName} // ...force the input's value to match the state variable...
onChange={e => setFirstName(e.target.value)} // ... and update the state variable on any edits!
/>
);
}

קלט מבוקר הגיוני אם בכל מקרה היית צריך state - לדוגמה, כדי לעבד מחדש את ממשק המשתמש שלך בכל עריכה:

function Form() {
const [firstName, setFirstName] = useState('');
return (
<>
<label>
First name:
<input value={firstName} onChange={e => setFirstName(e.target.value)} />
</label>
{firstName !== '' && <p>Your name is {firstName}.</p>}
...

זה גם useמלא אם ברצונך להציע מספר דרכים להתאים את הקלט state (לדוגמה, על ידי לחיצה על כפתור):

function Form() {
// ...
const [age, setAge] = useState('');
const ageAsNumber = Number(age);
return (
<>
<label>
Age:
<input
value={age}
onChange={e => setAge(e.target.value)}
type="number"
/>
<button onClick={() => setAge(ageAsNumber + 10)}>
Add 10 years
</button>

ה-value שתעביר לרכיבים מבוקרים לא אמור להיות undefined או null. אם אתה צריך שהערך ההתחלתי יהיה ריק (כגון עם השדה firstName למטה), אתחל את המשתנה state שלך למחרוזת ריקה ('').

import { useState } from 'react';

export default function Form() {
  const [firstName, setFirstName] = useState('');
  const [age, setAge] = useState('20');
  const ageAsNumber = Number(age);
  return (
    <>
      <label>
        First name:
        <input
          value={firstName}
          onChange={e => setFirstName(e.target.value)}
        />
      </label>
      <label>
        Age:
        <input
          value={age}
          onChange={e => setAge(e.target.value)}
          type="number"
        />
        <button onClick={() => setAge(ageAsNumber + 10)}>
          Add 10 years
        </button>
      </label>
      {firstName !== '' &&
        <p>Your name is {firstName}.</p>
      }
      {ageAsNumber > 0 &&
        <p>Your age is {ageAsNumber}.</p>
      }
    </>
  );
}

Pitfall

אם אתה מעביר את value ללא onChange, זה יהיה בלתי אפשרי להקליד בקלט. כאשר אתה שולט בקלט על ידי העברת כמה value אליו, אתה מאלץ אותו לקבל תמיד את הערך שהעברת. אז אם תעביר משתנה state בתור value אבל תשכח לעדכן את המשתנה state באופן סינכרוני במהלך מטפל האירועים onChange, React יחזיר את הקלט לאחר כל הקשה בחזרה ל-value שציינת.


אופטימיזציה של עיבוד מחדש בכל הקשה

כאשר אתה use קלט מבוקר, אתה מגדיר את state בכל הקשה. אם הרכיב המכיל את state שלך מעבד מחדש עץ גדול, זה יכול להיות איטי. יש כמה דרכים שבהן תוכל לייעל את ביצועי העיבוד מחדש.

לדוגמה, נניח שאתה מתחיל בטופס המציג מחדש את כל תוכן הדף בכל הקשה:

function App() {
const [firstName, setFirstName] = useState('');
return (
<>
<form>
<input value={firstName} onChange={e => setFirstName(e.target.value)} />
</form>
<PageContent />
</>
);
}

מכיוון ש<PageContent /> אינו מסתמך על הקלט state, אתה יכול להעביר את הקלט state לרכיב משלו:

function App() {
return (
<>
<SignupForm />
<PageContent />
</>
);
}

function SignupForm() {
const [firstName, setFirstName] = useState('');
return (
<form>
<input value={firstName} onChange={e => setFirstName(e.target.value)} />
</form>
);
}

זה משפר משמעותית את הביצועים מכיוון שuse כעת רק SignupForm מעבד מחדש בכל הקשה.

אם אין דרך להימנע מעיבוד מחדש (לדוגמה, אם PageContent תלוי בערך קלט החיפוש), useDeferredValue מאפשר לך לשמור על הקלט הנשלט תגובה אפילו באמצע עיבוד מחדש גדול.


פתרון בעיות

קלט הטקסט שלי לא מתעדכן כשאני מקליד בו

אם תציג קלט עם value אך ללא onChange, תראה שגיאה במסוף:

// 🔴 Bug: controlled text input with no onChange handler
<input value={something} />
Console
סיפקת אבזר value לשדה טופס ללא מטפל onChange. זה יציג שדה לקריאה בלבד. אם השדה צריך להיות ניתן לשינוי use defaultValue. אחרת, הגדר onChange או readOnly.

כפי שמציעה הודעת השגיאה, אם רק רצית לציין את הערך התחלתי, העבר את defaultValue במקום זאת:

// ✅ Good: uncontrolled input with an initial value
<input defaultValue={something} />

אם אתה רוצה לשלוט בקלט זה עם משתנה state, ציין מטפל onChange:

// ✅ Good: controlled input with onChange
<input value={something} onChange={e => setSomething(e.target.value)} />

אם הערך הוא בכוונה לקריאה בלבד, הוסף אבזר readOnly כדי לדכא את השגיאה:

// ✅ Good: readonly controlled input without on change
<input value={something} readOnly={true} />

תיבת הסימון שלי לא מתעדכנת כשאני לוחצת עליה

אם תציג תיבת סימון עם checked אך ללא onChange, תראה שגיאה במסוף:

// 🔴 Bug: controlled checkbox with no onChange handler
<input type="checkbox" checked={something} />
Console
סיפקת אבזר checked לשדה טופס ללא מטפל onChange. זה יציג שדה לקריאה בלבד. אם השדה צריך להיות ניתן לשינוי use defaultChecked. אחרת, הגדר onChange או readOnly.

כפי שמציעה הודעת השגיאה, אם רק רצית לציין את הערך התחלתי, העבר את defaultChecked במקום זאת:

// ✅ Good: uncontrolled checkbox with an initial value
<input type="checkbox" defaultChecked={something} />

אם אתה רוצה לשלוט בתיבת הסימון הזו עם משתנה state, ציין מטפל onChange:

// ✅ Good: controlled checkbox with onChange
<input type="checkbox" checked={something} onChange={e => setSomething(e.target.checked)} />

Pitfall

עליך לקרוא e.target.checked במקום e.target.value עבור תיבות סימון.

אם תיבת הסימון היא בכוונה לקריאה בלבד, הוסף אבזר readOnly כדי לדכא את השגיאה:

// ✅ Good: readonly controlled input without on change
<input type="checkbox" checked={something} readOnly={true} />

הקלט שלי קופץ להתחלה בכל הקשה

אם אתה שולט בקלט, עליך לעדכן את המשתנה state שלו לערך הקלט מה-DOM במהלך onChange.

אתה לא יכול לעדכן אותו למשהו אחר מלבד e.target.value (או e.target.checked עבור תיבות סימון):

function handleChange(e) {
// 🔴 Bug: updating an input to something other than e.target.value
setFirstName(e.target.value.toUpperCase());
}

אתה גם לא יכול לעדכן אותו באופן אסינכרוני:

function handleChange(e) {
// 🔴 Bug: updating an input asynchronously
setTimeout(() => {
setFirstName(e.target.value);
}, 100);
}

כדי לתקן את הקוד שלך, עדכן אותו באופן סינכרוני ל-e.target.value:

function handleChange(e) {
// ✅ Updating a controlled input to e.target.value synchronously
setFirstName(e.target.value);
}

אם זה לא פותר את הבעיה, ייתכן שהקלט יוסר ויתווסף מחדש מה-DOM בכל הקשה. זה יכול לקרות אם אתה מאפס בטעות state בכל עיבוד מחדש, למשל אם הקלט או אחד מההורים שלו תמיד מקבלים תכונה שונה key, או אם מקננים הגדרות של פונקציית רכיבים (שאינם נתמכים תמיד לרכיב K_4 וכא__T) עץ).


אני מקבל שגיאה: “רכיב משנה קלט לא מבוקר כדי להיות נשלט”

אם אתה מספק value לרכיב, הוא חייב להישאר מחרוזת לאורך כל חייו.

אתה לא יכול לעבור את value={undefined} קודם ומאוחר יותר לעבור את value="some string" כי use React לא תדע אם אתה רוצה שהרכיב יהיה לא מבוקר או נשלט. רכיב מבוקר צריך תמיד לקבל מחרוזת value, לא null או undefined.

אם ה-value שלך מגיע ממשתנה API או state, ייתכן שהוא מאותחל ל-null או undefined. במקרה כזה, הגדר אותו למחרוזת ריקה ('') בתחילה, או העבר את value={someValue ?? ''} כדי לוודא שvalue היא מחרוזת.

באופן דומה, אם תעביר את checked לתיבת סימון, ודא שהיא תמיד בוליאני.