استفاده از External Script در React

شاید برای شما پیش اومده باشه که بخواید یک فایل JavaScript رو بدون استفاده از import تو کامپوننت خودتون ازش استفاده کنید. مثلا شاید یک فایل JS دارید که بصورت CDN است و قراره فقط با کمک تگ Script اون رو تو صفحه اضافه و ازش استفاده کنید.

خوب با توجه به Lifecycle و داستان هایی که React برای رندر کردن DOM داره چیکار می کنید ؟

Using external script files into React component
Using external script files into React component

بهترین کار استفاده از متد componentDidMount هستش و باید یک تگ Script تو این متد بسازید و بعدا اون تگ رو append به body کنید. با فرض اینکه فایل جاوااسکریپت خودتون رو با نام test.js داخل مسیر Public (مثلا همون پوشه public که create-react-app میسازه !!!) قرار دادید همچین کدی رو بنویسید:

componentDidMount() {
    const script = document.createElement('script');
    script.src = './test.js';
    script.async = true;
    document.body(script);
}

خوب کد بالا خیلی ساده هستش , اومدیم یک تگ script ساختیم , بعدش مسیر src رو مشخص کردیم و اینکه مقدار async بودنش هم true و نهایتا append به body شده. اگر اون قضیه async رو متوجه نشدید می تونید مقاله زیر رو بخونید:

لینک مقاله: http://vrgl.ir/yDYwR

خوب الان ما یک تگ script رو اضافه کردیم و اگر یکسری کد داخل اون فایل test.js داشته باشید در زمان لود شدن برای شما همشون اجرا میشه.

کلا ما دو دسته کد داریم: یکی اجرا شونده و دومی سورس هایی که قراره بعدا ازشون استفاده کنیم.

تکلیف مورد اول که مشخصه , زمانیکه تگ script به صفحه اضافه بشه اجرا میشه و کار مشخص رو انجام میده. ولی برای React دردسر شما بیشتر سر همون مورد دوم و سورس هایی هست که قراره بعدا از توابع یا متغیرهاشون استفاده کنید و مثلا اونجا یک کلاس وجود داره که می خواید ازش یک Instance بسازید !!!

فرض کنید مثلا داخل فایل test.js همچین کدی رو دارید:

var userName = "Mohammad"
function showName() {
    console.log(userName);
}

حالا مثلا بیاید داخل یک متد از کامپوننت خودتون توی React این تابع رو اجرا کنید:

myMethod() {
    showName();
}

یا حتی مثلا بخواید از اون متغیر استفاده کنید:

myMethod() {
    console.log(userName);
}

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

ولی اشتباه می کنید و براتون میزنه: userName is not defined no-undef

بخاطر تقدم و تاخر و async بودن لود اسکریپت این مشکلات بوجود خواهد آمد و یکسری مسایل دیگه توضیح بیشتری داره که فعلا ازش عبور کنیم !!!

خوب راه حل این مشکل چیه ؟!

برای اینکه مشکل شما حل بشه و از اونجایی که توابع , کلاس ها و متغیرهای شما در test.js بصورت ماژولار export نشدن باید از و window استفاده کنید که مشکل حل بشه. مثلا برای متغیر userName میشه همچین حالتی رو در نظر گرفت:

componentDidMount() {
    const script = document.createElement('script');
    script.src = './test.js';
    script.async = true;
    script. = function() {
        if (window.userName !== null) {
            console.log(userName);
        }
    }
    document.body(script);
}

در بالا ما یک اضافه کردیم و میگیم زمان لود کامل اون تگ script بیاد این تابع رو اجرا کنه. داخلش هم دیگه مستقیم از userName استفاده نمی کنیم و چون به Global Variable ها احتیاج داریم از window استفاده کردیم که اگر برابر با null نبود بیاد ازش استفاده کنه !!! البته بصورت مستقیم بدون if هم قابل دسترس هستش , ولی بنظر من اگر شرط بزارید بهتره ...

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

تا آموزش و مقالات بعدی خدانگهدار

موفق باشید