تقریباً هر برنامه ای در برخی مواقع نیاز به پذیرش ورودی کاربر دارد و این معمولاً با فرم HTML قابل احترام و مجموعه کنترل های ورودی آن حاصل می شود. اگر اخیراً یادگیری React را شروع کرده اید ، احتمالاً به جایی رسیده اید که اکنون فکر می کنید ، “پس چگونه می توانم با فرم ها کار کنم؟”

این مقاله اصول استفاده از فرم ها را در React راهنمایی می کند تا به شما امکان می دهد اطلاعات را اضافه یا ویرایش کنید. ما به دو روش مختلف کار با کنترل های ورودی و جوانب مثبت و منفی هر یک نگاه خواهیم کرد. همچنین نگاهی خواهیم انداخت به نحوه رسیدگی به اعتبار سنجی و برخی از کتابخانه های شخص ثالث برای موارد استفاده پیشرفته تر.

ورودی های کنترل نشده

اساسی ترین روش کار با فرم ها در React استفاده از ورودی های فرم “غیر کنترل شده” است. معنی این امر این است که React وضعیت ورودی را ردیابی نمی کند. عناصر ورودی HTML به طور طبیعی وضعیت خود را به عنوان بخشی از DOM دنبال می کنند ، بنابراین بنابراین وقتی فرم ارسال می شود ، باید مقادیر موجود در خود عناصر DOM را بخوانیم.

به منظور انجام این کار ، React به ما اجازه می دهد تا “ref” (مرجع) ایجاد کنیم تا با یک عنصر ارتباط برقرار کند و به گره اصلی DOM دسترسی پیدا کند. بیایید ببینیم که چگونه این کار را انجام دهیم:

class SimpleForm extends React.Component {
  constructor(props) {
    super(props);
    
    this.nameEl = React.createRef();
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit(e) {
    e.preventDefault();
    alert(this.nameEl.current.value);
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>Name:
          <input type="text" ref={this.nameEl} />
        </label>
        <input type="submit" name="Submit" />
      </form>
    )
  }
}

همانطور که در بالا مشاهده می کنید ، برای یک کامپوننت مبتنی بر کلاس ، با فراخوانی یک ref جدید در سازنده شروع می کنید React.createRef، اختصاص دادن آن به یک خاصیت نمونه ، بنابراین در طول عمر ملفه در دسترس است.

به منظور مرتبط کردن ref با ورودی ، به عنصر به عنوان خاص منتقل می شود ref صفت. هنگامی که این کار انجام شد ، گره DOM ورودی ورودی از طریق قابل دسترسی است this.nameEl.current.

بیایید ببینیم که این چگونه در یک جز عملکردی به نظر می رسد:

function SimpleForm(props) {
  const nameEl = React.useRef(null);

  const handleSubmit = e => {
    e.preventDefault();
    alert(nameEl.current.value);
  };

  return (
     <form onSubmit={handleSubmit}>
       <label>Name:
         <input type="text" ref={nameEl} />
       </label>
       <input type="submit" name="Submit" />
     </form>
   );
}

در اینجا تفاوت زیادی وجود ندارد ، غیر از مبادله کردن createRef برای useRef قلاب.

مثال: فرم ورود به سیستم

function LoginForm(props) {
  const nameEl = React.useRef(null);
  const passwordEl = React.useRef(null);
  const rememberMeEl = React.useRef(null);

  const handleSubmit = e => {
    e.preventDefault();

    const data = {
      username: nameEl.current.value,
      password: passwordEl.current.value,
      rememberMe: rememberMeEl.current.checked,
    }

    
    
  };

  return (
     <form onSubmit={handleSubmit}>
       <input type="text" placeholder="username" ref={nameEl} />
       <input type="password" placeholder="password" ref={passwordEl} />
       <label>
         <input type="checkbox" ref={rememberMeEl} />
         Remember me
       </label>
       <button type="submit" className="myButton">Login</button>
     </form>
   );
}

مشاهده در CodePen

اگرچه ورودی های کنترل نشده برای فرم های سریع و ساده خوب کار می کنند ، اما اشکالاتی دارند. همانطور که ممکن است از کد بالا متوجه شده باشید ، هر زمان که بخواهیم باید عنصر ورودی را بخوانیم. این بدان معناست که ما نمی توانیم همانطور که کاربر تایپ می کنیم اعتبار فوری را در این زمینه ارائه دهیم و همچنین نمی توانیم کارهایی مانند اجرای قالب ورودی سفارشی ، نمایش یا پنهان کردن مشروط عناصر فرم یا غیرفعال کردن / فعال کردن دکمه ارسال را انجام دهیم.

خوشبختانه ، یک روش پیچیده تر برای مدیریت ورودی ها در React وجود دارد.

ورودی های کنترل شده

گفته می شود ورودی هنگامی کنترل می شود که React مسئول حفظ و تنظیم حالت خود باشد. حالت با مقدار ورودی همگام سازی می شود ، به این معنی که با تغییر ورودی ، وضعیت به روز می شود و با به روزرسانی حالت ، ورودی تغییر می کند.

بیایید ببینیم که با یک مثال چگونه به نظر می رسد:

class ControlledInput extends React.Component {
  constructor(props) {
    super(props);
    this.state = { name: '' };
    this.handleInput = this.handleInput.bind(this);
  }

  handleInput(event) {
    this.setState({
      name: event.target.value
    });
  }

  render() {
    return (
      <input type="text" value={this.state.name} onChange={this.handleInput} />
    );
  }
}

همانطور که مشاهده می کنید ، ما نوعی گردش داده دایره ای تنظیم می کنیم: وضعیت به مقدار ورودی ، تغییر رویداد به حالت و دوباره برگشت. این حلقه به ما امکان کنترل زیادی بر ورودی را می دهد ، زیرا می توانیم نسبت به تغییرات مقدار پرواز واکنش نشان دهیم. به همین دلیل ، ورودی های کنترل شده از محدودیت های ورودی کنترل نشده رنج نمی برند ، و این موارد زیر را باز می کند:

  • اعتبارسنجی ورودی فوری: ما می توانیم بدون نیاز به انتظار برای ارسال فرم ، بازخورد فوری به کاربر بدهیم (به عنوان مثال اگر رمز عبور وی به اندازه کافی پیچیده نباشد)
  • قالب بندی ورودی فوری: ما می توانیم جدا کننده های مناسب را به ورودی های ارزی یا گروه بندی به شماره تلفن های موجود اضافه کنیم
  • ارسال فرم را به طور مشروط غیرفعال کنید: ما می توانیم دکمه ارسال را پس از برآورده شدن معیارهای خاص فعال کنیم (به عنوان مثال کاربر با شرایط و ضوابط موافقت کرده است)
  • ورودی های جدید را به صورت پویا تولید می کند: ما می توانیم ورودی های اضافی را بر اساس ورودی قبلی کاربر به فرم اضافه کنیم (به عنوان مثال اضافه کردن اطلاعات افراد اضافی در رزرو هتل)

اعتبار سنجی

همانطور که در بالا اشاره کردم ، حلقه به روزرسانی مداوم اجزای کنترل شده امکان انجام اعتبار سنجی مداوم بر روی ورودی ها را به عنوان نوع کاربر فراهم می کند. یک کنترل کننده متصل به ورودی ها onChange رویداد با هر ضربه کلید شلیک می شود ، به شما امکان می دهد فورا مقدار را تأیید یا قالب بندی کنید.

مثال: اعتبار کارت اعتباری

بیایید نگاهی به یک مثال واقعی از بررسی شماره کارت اعتباری در هنگام تایپ کاربر در فرم پرداخت بیندازیم.

مثال از کتابخانه ای به نام استفاده می کند نوع کارت اعتباری برای تعیین صادر کننده کارت (مانند Amex ، Visa یا Mastercard) به عنوان انواع کاربر. سپس م componentلفه از این اطلاعات برای نمایش تصویری از آرم صادر کننده در کنار ورودی استفاده می کند:

import  creditCardType  from  "credit-card-type";

function CreditCardForm(props) {
  const [cardNumber, setCardNumber] = React.useState("");
  const [cardTypeImage, setCardTypeImage] = React.useState(
    "card-logo-unknown.svg"
  );

  const handleCardNumber = (e) => {
    e.preventDefault();

    const value = e.target.value;
    setCardNumber(value);

    let suggestion;

    if (value.length > 0) {
      suggestion = creditCardType(e.target.value)[0];
    }

    const cardType = suggestion ? suggestion.type : "unknown";

    let imageUrl;

    switch (cardType) {
      case "visa":
        imageUrl = "card-logo-visa.svg";
        break;
      case "mastercard":
        imageUrl = "card-logo-mastercard.svg";
        break;
      case "american-express":
        imageUrl = "card-logo-amex.svg";
        break;
      default:
        imageUrl = "card-logo-unknown.svg";
    }

    setCardTypeImage(imageUrl);
  };

  return (
    <form>
      <div className="card-number">
        <input
          type="text"
          placeholder="card number"
          value={cardNumber}
          onChange={handleCardNumber}
        />
        <img src={cardTypeImage} alt="card logo" />
      </div>
      <button type="submit" className="myButton">
        Login
      </button>
    </form>
  );
}

ورودی ها onChange مدیر تماس می گیرد creditCardType() عملکرد با مقدار فعلی. این یک آرایه تطابق (یا یک آرایه خالی) را برمی گرداند که می تواند برای تعیین اینکه کدام تصویر نمایش داده می شود استفاده شود. سپس URL تصویر بر روی یک متغیر حالت تنظیم می شود تا در فرم ارائه شود.

می توانید از برخی از اعداد از استفاده کنید اینجا برای تست ورودی.

کتابخانه ها را تشکیل دهید

همانطور که ممکن است متوجه شده باشید ، هنگام کار با فرم ها مقدار مشخصی از کد صفحه دیگ بخار وجود دارد ، خصوصاً اینکه باید ورودی ها را با مقادیر حالت و کنترل کننده های آنها سیم کنید. همانطور که انتظار دارید ، کتابخانه های شخص ثالث متنوعی برای کمک به تسکین درد در برخورد با اشکال بزرگتر و پیچیده تر وجود دارد.

برای اینکه بتوانید ایده استفاده از کتابخانه فرم را به شما ارائه دهیم ، بیایید نگاهی گذرا به یک نامیده شده بیندازیم تازه. هدف این کتابخانه پوشش دادن 90٪ موارد معمول استفاده شما با یک API ساده و با کاربرد آسان است. در اینجا مثالی از فرم ویرایش نمایه را مشاهده می کنید که می توانید در یک برنامه وب پیدا کنید:

import { Form, Field } from "@leveluptuts/fresh";

const securityQuestions = [
  "What is your mother's maiden name?",
  "What was the name of your first pet?",
  "What was the name of your first school?"
];

const handleSubmit = (data) => console.log(data);

function UserProfileForm() {
  return (
    <Form formId="user-profile" onSubmit={handleSubmit}>
      <Field required>First Name</Field>
      <Field required>Last Name</Field>
      <Field required type="email">
        Email
      </Field>

      <Field required type="select" options={securityQuestions}>
        Security Question
      </Field>
      <Field required>Security Answer</Field>

      <Field type="textarea">Bio</Field>
    </Form>
  );
}

Fresh برخی از اجزای سفارشی را برای ایجاد فرم های بسیار ساده فراهم می کند. Field جز component از سیم کشی اتصال داده ها روی ورودی فرم مراقبت می کند و برچسبی را که ارائه می دهید به مقدار خاصیت شتر برای مقدار ورودی تبدیل می کند. (به عنوان مثال ، “نام خانوادگی” می شود lastName در حالت فرم.)

Form کامپوننت تمام فیلدها را میپیچد و یک onSubmit فراخوانی که داده های فرم را به عنوان یک شی دریافت می کند. در زیر مثالی از خروجی فرم آورده شده است:

{
  firstName: "Bill",
  lastName: "Gates",
  email: "billg@microsoft.com",
  securityQuestion: "What was the name of your first pet?",
  securityAnswer: "Fluffy",
  bio: "Bill Gates is a technologist, business leader, and philanthropist. He grew up in Seattle, Washington, with an amazing and supportive family who encouraged his interest in computers at an early age."
}

همانطور که مشاهده می کنید ، کتابخانه هایی از این دست می توانند سرعت کار با فرم ها را سرعت بخشیده و م componentsلفه های شما را بسیار کمتر بیان کنند. برای هر چیزی به غیر از فرم اولیه و کوچک ، توصیه می کنم متناسب با نیاز شما انتخاب شود ، زیرا در طولانی مدت در وقت شما صرفه جویی می کند.

نتیجه

اکنون باید درک کاملی از نحوه استفاده از فرم ها و ورودی ها در React داشته باشید. شما باید تفاوت بین ورودی های کنترل شده و کنترل نشده و جوانب مثبت و منفی هر یک را بدانید ، زیرا باید توجه داشته باشید که حلقه تنگ بروزرسانی ورودی کنترل شده به شما امکان گزینه های زیادی برای قالب بندی و اعتبارسنجی مقادیر موجود را می دهد. در آخر ، باید توجه داشته باشید که کتابخانه های فرم موجود است که از شما در اضافه کردن کد دیگ بخار تکراری و پر حرف به فرم React خود جلوگیری می کند ، که به شما کمک می کند تا یک توسعه دهنده سازنده تر باشید.