<קלט>
רכיב הדפדפן המובנה <input> מאפשר לך להציג סוגים שונים של קלט טפסים.
<input />הפניה
<input>
כדי להציג קלט, רנדר את הדפדפן המובנה <input> רכיב.
<input name="myInput" />אבזרים
<input> תומך בכל הרכיב המשותף props.
formAction: מחרוזת או פונקציה. עוקפת את האב <form action> עבור type="submit" וtype="image". כאשר כתובת URL מועברת ל-action הטופס יתנהג כמו טופס HTML סטנדרטי. כאשר פונקציה תועבר ל-formAction הפונקציה תטפל בטופס ההגשה. <form action>.
אתה יכול להפוך קלט מבוקר על ידי העברת אחד מה-props הבאים:
checked: בוליאני. עבור קלט תיבת סימון או לחצן בחירה, שולט אם הוא נבחר.value: מחרוזת. עבור קלט טקסט, שולט בטקסט שלו. (עבור לחצן בחירה, מציין את נתוני הטופס שלו.)
כאשר אתה עובר אחד מהם, עליך לעבור גם מטפל onChange שמעדכן את הערך שעבר.
<input> props אלו רלוונטיים רק לכניסות לא מבוקרות:
defaultChecked: בוליאני. מציין את הערך ההתחלתי עבור כניסותtype="checkbox"וtype="radio".defaultValue: מחרוזת. מציין את הערך ההתחלתי עבור קלט טקסט.
<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> ); }
שליטה בקלט עם משתנה 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> } </> ); }
אופטימיזציה של עיבוד מחדש בכל הקשה
כאשר אתה 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} />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} />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)} />אם תיבת הסימון היא בכוונה לקריאה בלבד, הוסף אבזר 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 לתיבת סימון, ודא שהיא תמיד בוליאני.