רכיב הדפדפן המובנה <textarea> מאפשר לך לעבד קלט טקסט מרובה שורות.

<textarea />

הפניה

<textarea>

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

<textarea name="postContent" />

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

אבזרים

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

אתה יכול להפוך אזור טקסט לשלוט על ידי העברת אבזר value:

  • value: מחרוזת. שולט בטקסט בתוך אזור הטקסט.

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

אם ה-<textarea> שלך לא מבוקר, אתה יכול להעביר את הפרופס של defaultValue במקום זאת:

<textarea> props אלו רלוונטיים הן עבור אזורי טקסט בלתי נשלטים והן עבור אזורי טקסט מבוקרים:

  • autoComplete: או 'on' או 'off'. מציין את אופן ההשלמה האוטומטית.
  • autoFocus: בוליאני. אם true, React ימקד את האלמנט ב-mount.
  • children: <textarea> אינו מקבל ילדים. כדי להגדיר את הערך ההתחלתי, use defaultValue.
  • cols: מספר. מציין את רוחב ברירת המחדל ברוחב תווים ממוצע. ברירת המחדל היא 20.
  • disabled: בוליאני. אם true, הקלט לא יהיה אינטראקטיבי ויופיע מעומעם.
  • form: מחרוזת. מציין את id של <form> שהקלט הזה שייך אליו. אם מושמט, זה טופס האב הקרוב ביותר.
  • maxLength: מספר. מציין את האורך המרבי של הטקסט.
  • minLength: מספר. מציין את האורך המינימלי של הטקסט.
  • name: מחרוזת. מציין את השם עבור הקלט הזה שנשלח עם הטופס.
  • onChange: פונקציה Event מטפל. נדרש עבור אזורי טקסט מבוקרים. מופעל מיד כאשר ערך הקלט משתנה על ידי ה-user (לדוגמה, הוא מופעל בכל הקשה). מתנהג כמו הדפדפן input אירוע.
  • onChangeCapture: גרסה של onChange שנורה בשלב לכידה.
  • פונקציה onInput: מטפל Event. מופעל מיד כשהערך משתנה על ידי ה-user. מסיבות היסטוריות, ב-React זה עובד בצורה אידיומטית ל-__TK___5.
  • onInputCapture: גרסה של onInput שנורה בשלב לכידה.
  • פונקציה onInvalid: מטפל Event. מופעל אם קלט נכשל באימות בשליחת הטופס. בניגוד לאירוע המובנה invalid, האירוע React __TK בועות
  • onInvalidCapture: גרסה של onInvalid שנורה בשלב לכידה.
  • פונקציה onSelect: מטפל Event. מופעל לאחר שהבחירה בתוך <textarea> משתנה. React מרחיב את האירוע onSelect כך שישפיע גם על הבחירה הריקה שלו.
  • onSelectCapture: גרסה של onSelect שנורה בשלב לכידה.
  • placeholder: מחרוזת. מוצג בצבע מעומעם כאשר ערך אזור הטקסט ריק.
  • readOnly: בוליאני. אם true, אזור הטקסט אינו ניתן לעריכה על ידי ה-user.
  • required: בוליאני. אם true, יש לספק את הערך כדי שהטופס יישלח.
  • rows: מספר. מציין את גובה ברירת המחדל בגבהי תווים ממוצעים. ברירת המחדל היא 2.
  • wrap: או 'hard', 'soft', או 'off'. מציין כיצד יש לעטוף את הטקסט בעת שליחת טופס.

אזהרות

  • אסור להעביר ילדים כמו <textarea>something</textarea>. השתמש ב-defaultValue לתוכן ראשוני.
  • אם אזור טקסט מקבל מחרוזת value אבזר, הוא יטופל כבולט.](#controlling-a-text-area-with-a-state-variable)
  • אזור טקסט לא יכול להיות נשלט ובלתי נשלט בו זמנית.
  • אזור טקסט לא יכול לעבור בין נשלט או בלתי נשלט במהלך חייו.
  • כל אזור טקסט מבוקר צריך מטפל אירועים onChange שמעדכן באופן סינכרוני את ערך הגיבוי שלו.

שימוש

הצגת אזור טקסט

עיבוד <textarea> כדי להציג אזור טקסט. אתה יכול לציין את גודל ברירת המחדל שלו עם המאפיינים rows ו-cols, אך כברירת מחדל ה-user יוכל לשנות את גודלו. כדי לבטל שינוי גודל, ניתן לציין resize: none ב-CSS.

export default function NewPost() {
  return (
    <label>
      Write your post:
      <textarea name="postContent" rows={4} cols={40} />
    </label>
  );
}


מתן תווית לאזור טקסט

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

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

import { useId } from 'react';

export default function Form() {
  const postTextAreaId = useId();
  return (
    <>
      <label htmlFor={postTextAreaId}>
        Write your post:
      </label>
      <textarea
        id={postTextAreaId}
        name="postContent"
        rows={4}
        cols={40}
      />
    </>
  );
}


מתן ערך ראשוני עבור אזור טקסט

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

export default function EditPost() {
  return (
    <label>
      Edit your post:
      <textarea
        name="postContent"
        defaultValue="I really enjoyed biking yesterday!"
        rows={4}
        cols={40}
      />
    </label>
  );
}

Pitfall

שלא כמו ב-HTML, העברת טקסט ראשוני כמו <textarea>Some content</textarea> אינה נתמכת.


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

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

export default function EditPost() {
  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>
        Post title: <input name="postTitle" defaultValue="Biking" />
      </label>
      <label>
        Edit your post:
        <textarea
          name="postContent"
          defaultValue="I really enjoyed biking yesterday!"
          rows={4}
          cols={40}
        />
      </label>
      <hr />
      <button type="reset">Reset edits</button>
      <button type="submit">Save post</button>
    </form>
  );
}

Note

תן name ל-<textarea> שלך, למשל <textarea name="postContent" />. ה-name שציינת יהיה used כמפתח בנתוני הטופס, למשל { postContent: "Your post" }.

Pitfall

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


שליטה באזור טקסט עם משתנה state

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

כדי לעבד אזור טקסט נשלט, העבירו אליו את האביזר value. React יאלץ את אזור הטקסט לכלול תמיד את ה-value שעברת. בדרך כלל, תוכל לשלוט באזור טקסט על ידי הכרזה על משתנה state:

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

זה useמלא אם ברצונך לעבד מחדש חלק כלשהו ממשק המשתמש בתגובה לכל הקשה.

{
  "dependencies": {
    "react": "latest",
    "react-dom": "latest",
    "react-scripts": "latest",
    "remarkable": "2.0.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "devDependencies": {}
}

Pitfall

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


פתרון בעיות

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

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

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

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

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

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

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

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

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

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

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

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

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, או אם אתה מקנן הגדרות רכיבים (מה שאסור ב-React וב-causes של הרכיב ה”פנימי” להתקין מחדש בכל עיבוד).


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

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

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

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