کامپوننت کنترل شده و کنترل نشده در ری اکت — راهنمای کاربردی

۴۱۲ بازدید
آخرین به‌روزرسانی: ۰۵ مهر ۱۴۰۲
زمان مطالعه: ۴ دقیقه
کامپوننت کنترل شده و کنترل نشده در ری اکت — راهنمای کاربردی

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

در اغلب موارد پیشنهاد می‌کنیم از «کامپوننت‌های کنترل‌شده» (Controlled Components) برای پیاده‌سازی فرم‌ها استفاده کنید. در یک کامپوننت کنترل‌شده، داده‌های فرم از سوی یک کامپوننت ری‌اکت مدیریت می‌شود. جایگزین آن کامپوننت کنترل نشده است که در آن داده‌های فرم از سوی خود DOM مدیریت می‌شوند. در ادامه هر یک از آن‌ها را مورد بررسی قرار می‌دهیم.

کامپوننت‌های کنترل شده

در یک کامپوننت کنترل‌شده، داده‌های فرم از سوی حالت (State) درون کامپوننت مدیریت می‌شوند. این حالت درون کامپوننت به صورت یک «منبع منفرد واقعیت» برای عناصر ورودی که از سوی کامپوننت رندر می‌شوند، عمل می‌کند.

به مثال کد زیر توجه کنید:

1import React, { Component } from 'react';
2
3class App extends Component {
4    state = {
5        message: ''
6    }
7    updateMessage = (newText) => {
8        console.log(newText);
9        this.setState(() => ({
10            message: newText
11        }));
12    }
13    render() {
14        return (
15            <div className="App">
16                <div className="container">
17                    <input type="text"
18                        placeholder="Your message here.."
19                        value={this.state.message}
20                        onChange={(event) => this.updateMessage(event.target.value)}
21                    />
22                    <p>the message is: {this.state.message}</p>
23                </div>
24            </div>
25        );
26    }
27}
28
29export default App;

در این کد یک کامپوننت ساده داریم که یک textbox را روی صفحه رندر کرده و مواردی که کاربر در آن وارد می‌کند را echo می‌کند. طرز کار آن به صورت زیر است:

اگر به کد این کامپوننت نگاه کنیم، در خط 4 یک شیء حالت ایجاد می‌کنیم. این شیء یک مشخصه منفرد به نام message نگهداری می‌کند. این همان جایی است که مقدار وارد شده در textbox ذخیره می‌شود.

برای ذخیره یک مقدار، باید در زمان وارد شدن آن از سوی کاربر در textbox یک رویداد ایجاد کنیم. اگر به خطوط 19 و 20 کد فوق نگاه کنید، می‌بینید که:

  • Textbox یک خصوصیت مقداری دارد که به مشخصه message در حالت پیوند یافته است.
  • یک دستگیره رویداد onChange نیز تعریف شده است.

این دو مورد مشخص می‌سازند که با یک کامپوننت کنترل‌شده روبرو هستیم. برای این که یک کامپوننت به صورت کامپوننت کنترل‌شده باشد، نیازی به یک عنصر فرم روی صفحه نداریم. زمانی که در هر یک از عناصر ورودی تغییری ایجاد شود، دستگیره رویداد مربوطه تحریک می‌شود. این دستگیره چنان که در خط 9 کد فوق می‌بینید، (()setState را فرا می‌خواند. بدین ترتیب حالت درون کامپوننت به‌روزرسانی می‌شود.

هرگز نباید حالت را مستقیماً به صورت زیر تعیین کنید:

this.state.message = 'dont update state like this';

به‌روزرسانی حالت به این صورت موجب رندر مجدد کامپوننت نمی‌شود و از این رو تغییر انجام یافته از سوی کاربر در UI نمایش نمی‌یابد. زمانی که یک به‌روزرسانی حالت از طریق ()setState رخ می‌دهد، کامپوننت رندر مجدد می‌شود و مقدار جدیداً وارد شده در عنصر نمایش می‌یابد.

گردش داده به صورت یک‌طرفه از حالت کامپوننت به عنصر ورودی است. کار کردن با کامپوننت‌های کنترل‌شده ممکن است کمی پیچیده باشد و اگر تعداد زیادی عناصر ورودی روی صفحه باشند، هر یک نیازمند تنظیم خاص خود با یک خصوصیت value و یک event handler هستند.

کامپوننت‌های کنترل نشده

کامپوننت‌های کنترل نشده بیشتر شبیه عناصر معمولی فرم HTML هستند. داده‌های هر عنصر ورودی در DOM و نه در کامپوننت ذخیره می‌شوند. به جای نوشتن یک دستگیره رویداد برای همه به‌روزرسانی‌های حالت، از ref برای دریافت مقادیر از DOM استفاده می‌کنیم. اگر کنجکاو هستید که ref چیست، در ادامه تعریف آن را از مستندات ارائه کرده‌ایم:

Ref روشی برای دسترسی به گره‌های DOM یا عناصر ری‌اکت ایجاد شده در متد رندر ارائه می‌کند.

به مثال کد زیر توجه کنید. اگر کامپوننت کنترل‌شده را که در مثال قبل ارائه کردیم به یک کامپوننت کنترل نشده تبدیل کنیم، کد به صورت زیر درمی‌آید:

1import React, { Component } from 'react';
2
3class App2 extends Component {
4    constructor(props){
5        super(props);
6        this.handleChange = this.handleChange.bind(this);
7        this.input = React.createRef();
8    }
9    
10    handleChange = (newText) => {
11        console.log(newText);
12    }
13    render() {
14        return (
15            <div className="App2">
16                <div className="container">
17                    <input type="text"
18                        placeholder="Your message here.."
19                        ref={this.input}
20                        onChange={(event) => this.handleChange(event.target.value)}
21                    />
22                </div>
23            </div>
24            
25        );
26    }
27}
28export default App2;

همچنان که می‌بینید یک سازنده در خط 4 اضافه کرده‌ایم که در آن یک دستگیره رویداد تنظیم می‌کنیم و یک ref برای اشاره به this.input می‌سازیم. همچنین بار دیگر در خط 19 به this.input ارجاع داده‌ایم که آن را به صورت خصوصیت ref روی عنصر ورودی تنظیم می‌کنیم. با کنار هم قرار گرفتن این قطعات، هر بار که متنی را در textbox وارد می‌کنیم، مقدار مورد نظر در کنسول پرینت می‌شود.

 

 

چند نکته کلیدی که در مورد ref باید توجه داشته باشیم به شرح زیر هستند:

  • Ref-ها با استفاده از ()React.createRef ایجاد می‌شوند.
  • Ref-ها با استفاده از خصوصیت روی عنصر مورد بحث به عناصر ورودی اتصال می‌یابند.
  • Ref-ها در اغلب موارد به عنوان مشخصه‌های وهله‌ای روی یک کامپوننت مورد استفاده قرار می‌گیرند. Ref در سازنده (چنان که در مثال قبل دیدیم) تعیین می‌شود و مقدار آن در سراسر کامپوننت در اختیار ما خواهد بود.

نمی‌توانید از خصوصیت ref روی کامپوننت‌های تابعی استفاده کنید، زیرا یک وهله ایجاد نشده است. به مثال زیر توجه کنید:

1//This will not work
2
3function MyComponent() {
4  return <input />; 
5}
6
7class MyOtherComponent extends Component {
8 constructor(props) {
9   super(props);
10   this.textInput = React.createRef();
11 }  
12  render() {
13   return (
14     <MyComponent ref={this.textInput} />
15   ); 
16  }
17}

اما می‌توانید از یک خصوصیت ref درون یک کامپوننت تابعی به صورت زیر استفاده کنید:

1function MyInput(props) {
2  let theInput = React.createRef();
3  function setFocus() {
4    textInput.current.focus();
5  }  
6  return(
7    <div>
8      <input type="text" ref="{theInput}" />
9      <button value="set focus" onClick={setFocus} />
10  );
11}

در مستندات ری‌اکت برخی از کاربردهای مفید دیگر Ref-ها به صورت مدیریت فوکوس، انتخاب متن، یا بازپخش مدیا، تحریک انیمیشن‌های دستوری، یکپارچه‌سازی در کتابخانه‌های شخص ثالث DOM توضیح داده شده است. همچنین توضیح شده است که از Ref-ها برای هر چیزی که می‌تواند به صورت اعلانی انجام یابد، استفاده نکنیم.

سخن پایانی

  1. هر زمان که ممکن است از کامپوننت‌های کنترل‌شده استفاده کنید.
  2. کامپوننت‌های کنترل‌شده برای این که یک کامپوننت کنترل‌شده تلقی شوند، نیازمند یک عنصر فرم نیستند.
  3. اگر یک کامپوننت دارای عنصر ورودی باشد که خصوصیت value آن به state پیوند یافته باشد و یک دستگیره رویداد برای به‌روزرسانی حالت مذکور داشته باشد، کامپوننت کنترل‌شده است.
  4. برای صفحه‌هایی که تعداد عناصر ورودی زیادی دارند، کار با کامپوننت‌های کنترل‌شده ممکن است دشوار باشد.
  5. گردش داده در کامپوننت‌های کنترل‌شده تک جهتی است و حالت درون کامپوننت به عنوان تنها منبع معتبر حقیقت عمل می‌کند.
  6. همه تغییرات حالت درون کامپوننت کنترل‌شده باید از طریق تابع setState انجام یابد.
  7. کامپوننت‌های کنترل نشده داده‌هایشان را در DOM مانند عناصر ورودی HTML سنتی عمل می‌کنند.
  8. ()React.createRef برای ایجاد متغیرهای وهله‌ای درون ساختارهای کامپوننت کنترل نشده عمل می‌کند. این متغیرها در ادامه از طریق خصوصیت ref با عناصر ورودی مرتبط می‌شود.
  9. Ref-ها نمی‌توانند روی کامپوننت‌های تابعی استفاده شوند، زیرا هیچ وهله‌ای ندارد.
  10. Ref-ها می‌توانند درون کامپوننت‌های تابعی مورد استفاده قرار گیرند.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

^^

بر اساس رای ۳ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
itnext
۲ دیدگاه برای «کامپوننت کنترل شده و کنترل نشده در ری اکت — راهنمای کاربردی»

دو تا کد پایین که شبیه همه

سلام، وقت شما بخیر؛

این مورد بررسی و اصلاح شده است.

از تذکر به جای شما و همراهی‌تان با مجله فرادرس بسیار سپاسگزاریم.

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *