سلام در بخش پنجم آموزش React Native , مدیریت ورودی های متنی,مدیریت ورودی های touch,استفاده از Scroll View ,استفاده از List View در React Native را یاد گرفتید.
با بخش ششم آموزش React Native همراه ما باشید.
ارتباطات تحت شبکه در React Native Apps:
اغلب application های موبایل منابع خود را از شبکه load می کنند. ممکن است بخواهید یک POST request به یک REST API بزنید، یا محتوایی ثابت از یک سرور بگیرید.
استفاده از Fetch
ری اکت ، Fetch API را برای کارهای تحت شبکه در اختیار می گذارد. اگر از XMLHttpRequest یا API های دیگر استفاده کرده باشید با fetch آشنایید. می توانید برای مطالعه ی بیشتر به راهنمای MDN درمورد نحوه استفاده از Fetch مراجعه کنید.
Request
برای دریافت محتوا از یک آدرس فرضی، کافی است آدرس را به () fetchبدهید:
fetch('https://mywebsite.com/mydata.json');
همچنین fetch یک آرگومان دیگر هم می تواند بگیرد و به شما امکان کنترل بیشتری روی HTTP request بدهد. ممکن است بخواهید header اضافه کنید، یا یک request POST بزنید:
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
}),
});
برای لیست کامل property ها سری به مستندات Fetch Request بزنید.
مدیریت Response ها
مثال بالا نحوه ارسال یک request را نشان می دهد. در بسیاری موارد ممکن است بخواهید روی response سرور کاری انجام دهید.
ارتباطات در شبکه ذاتا async هستند. متد Fetch یک Promise برمی گرداند که نوشتن کد برای سناریوهای async را آسان می کند:
function getMoviesFromApiAsync() {
return fetch('https://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
return responseJson.movies;
})
.catch((error) => {
console.error(error);
});
}
میتوان از دستور async/await در ES2017 نیز در یک application React Native استفاده کرد:
async function getMoviesFromApi() {
try {
let response = await fetch(
'https://facebook.github.io/react-native/movies.json',
);
let responseJson = await response.json();
return responseJson.movies;
} catch (error) {
console.error(error);
}
}
فراموش نکنید که خطاهای ممکن هنگام کار با fetch را catch کنید، در غیر این صورت هیچ هشداری نخواهد بود.
import React from 'react';
import { FlatList, ActivityIndicator, Text, View } from 'react-native';
export default class FetchExample extends React.Component {
constructor(props){
super(props);
this.state ={ isLoading: true}
}
componentDidMount(){
return fetch('https://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson.movies,
}, function(){
});
})
.catch((error) =>{
console.error(error);
});
}
render(){
if(this.state.isLoading){
return(
<View style={{flex: 1, padding: 20}}>
<ActivityIndicator/>
</View>
)
}
return(
<View style={{flex: 1, paddingTop:20}}>
<FlatList
data={this.state.dataSource}
renderItem={({item}) => <Text>{item.title}, {item.releaseYear}</Text>}
keyExtractor={({id}, index) => id}
/>
</View>
);
}
}
به طور پیش فرض iOS تمام request هایی را که encryp نشده اند و از SSL استفاده نمی کنند block می کند. اگر می خواهید از آدرسی بدون SSL، دیتا بگیرید ابتدا باید یک App Transport Security exception اضافه کنید. اگر از قبل می دانید که کدام دامنه ها استفاده می شوند، بهتر است فقط برای آن دامنه ها exception اضافه کنید. اگر دامنه ها تا زمان اجرا مشخص نیستند می توانید ATS را کامل غیرفعال کنید. البته از ابتدای 2017، برای غیرفعال کردن ATS به دلیلی موجه احتیاج دارد. مستندات Apple را برای اطلاعات بیشتر ببینید.
استفاده از کتابخانه های دیگر
ایکس ام ال XMLHttpRequest API در React Native هست، به این معنا که شما می توانید از کتابخانه های فرعی مثل frisbee یا Axios که براساس آن نوشته شده اند استفاده کنید، یا خود XMLHttpRequest API را مستقیما استفاده کنید.
var request = new XMLHttpRequest();
request. = (e) => {
if (request.readyState !== 4) {
return;
}
if (request.status === 200) {
console.log('success', request.responseText);
} else {
console.warn('error');
}
};
request.open('GET', 'https://mywebsite.com/endpoint/');
request.send();
امنیت برای XMLHttpRequest در application ها متفاوت از web است، چرا که مفهوم CORS در application معنا ندارد.
پشتیبانی از Web Socket
ری اکت React Native از Web Socket نیز پشتیبانی می کند، پروتکلی که کانال های دوطرفه ارتباطی را روی یک ارتباط TCP فراهم می کند:
var ws = new WebSocket('ws://host.com/path');
ws.onopen = () => {
// connection opened
ws.send('something'); // send a message
};
ws. = (e) => {
// a message was received
console.log(e.data);
};
ws. = (e) => {
// an error occurred
console.log(e.message);
};
ws. = (e) => {
// connection closed
console.log(e.code, e.reason);
};
مشکلات رایج در رابطه با fetch و احراز هویت مبتنی بر کوکی ها (cookie based authentication)
استفاده از موارد زیر هنگام کار با fetch، فعلا ممکن نیست:
· استفاده از redirect:manual
· استفاده از credentials:omit
· داشتن header های با نام یکسان در android. یک راه حل موقت در این لینک قابل پیاده سازی است.
· احراز هویت مبتنی بر Cookie فعلا ناپایدار است. می توانید issue های مشابه را در اینجا ببینید.
· در iOS وقتی خطای 302 اتفاق می افتد، اگر در کوکی Set-Cookie وجود داشته باشد، Cookie به درستی set نمی شود. از آنجا که redirect نمی تواند دستی انجام شود، اگر redirect حاصل یک session expired باشد، ممکن است request ها درون یک infinite loop بیفتد.
منابع دیگر در حوزه React Native
تا اینجای کار را با ما همراه بودید، اکنون می توانید یک application React Native برای خودتان بنویسید. اما React Native فقط یک محصول نیست، بلکه جامعه ای از توسعه دهندگان است. اگر به React Native علاقه مند هستید، مواردی هست که ممکن است بخواهید سری به آن بزنید:
کتابخانه های معروف
اگر از React Native استفاده می کنید، احتمالا با React آشنا هستید. اگر درمورد React چیزی نمی دانید، React بهترین راه برای ساخت یک وب سایت مدرن است. حتما کار با آن را تجربه کنید.
یکی از سوالات رایج این است که چطور "state" application React Native خود را کنترل کنیم. معروف ترین کتابخانه برای این کار Redux است. Redux کتابخانه ای ساده است و فیلم های آموزشی آن نیز موجود است.
اگر دنبال کتابخانه ای برای کاری خاص می گردید، Awesome React Native را چک کنید. لیستی از component ها با پیش نمایش و مقالات مرتبط و... در دسترس خواهد بود.
مثال ها
اگر به دنبال قابلیت های application های React Native هستید، Showcase را ببینید. همچنین، مثال هایی در Github موجود هستند. می توانید این application ها را در شبیه ساز یا device خود ببینید، و میتوانید source code ها را استفاده کنید.
سازندگان applicationبرای Facebook&amp;#x27;s F8 کد آن را متن باز در اختیار عموم گذاشته اند و سری آموزش های خوبی برای آن هست. اگر دنبال مثال های واقعی تر و عمیق تری هستید، سری به آن بزنید.
توسعه ی React Native
توسعه دهندگان ماژول های React Native خود را می سازند و در npm منتشر می کنند و کد آن را در Github به اشتراک می گذارند.
ساخت ماژول به اکوسیستم React Native کمک می کند. شما هم این کار را انجام دهید.
راهنما های مربوط به ماژول های native(برای iOS و android)، و component های native برای UI (برای iOS و android) را بخوانید. (لینک ها درون همین آموزش)
اگر دنبال component های آماده می گردید سری به JS.coach یا Native Directory بزنید.
ابزارهای توسعه
در ری اکت Nuclide یک IDE است که Facebook برای توسعه ی جاوااسکریپت از آن استفاده می کند که قابلیت فوق العاده ای در debug دارد. VS Code هم IDE دیگری است که بین توسعه دهندگان جاوااسکریپت معروف است.
در ری اکت Ignite یک package خوب برای شروع است که از Redux و کتابخانه های حاوی component های UI دیگر استفاده می کند. همچنین، برای تولید application، component و container، میتوان از CLI آن استفاده کرد.
در ری اکت App Center سرویسی از Microsoft است که deploy بروزرسانی های لحظه ای application را آسان می کند. اگر نمی خواهید برای deploy درگیر پروسه App Store ها شوید و نمی خواهید backend خودتان را داشته باشید، آن را امتحان کنید.
در ری اکت Expo یک محیط توسعه است که به شما امکان ساخت application های React Native بدون نیاز به xcode یا Android Studio را می دهد.
در ری اکت Yoga ابزاری برای ساخت layout است که امکان ساخت انواع layout برای پلتفرم های مختلف را می دهد.
در ری اکت Bugsnag، Microsoft App Center و Sentry، همه سرویس های خوبی برای نظارت به نحوه کار application های React Native ارائه می دهند. این سرویس ها به شما امکان مانیتورcrash ها و مشکلات app به صورت real time را می دهد و می توانید سریعا آن را رفع کنید.
ابزار React Developer Tools برای debug اپلیکیشن های React و React Native عالی است.
تنظیماتی برای بهبود عملکرد Flatlist در React Native
اصطلاحات
در ری اکت VirtualizedList: component پایه ی FlatList (پیاده سازی React Native از مفهوم virtual List)
در ری اکت Memory consumption: میزان اطلاعات از لیست که در حافظه نگه داری می شود، که ممکن است منجر به توقف ناگهانی application شود.
در ری اکت Responsiveness: توانایی application برای پاسخ به تعاملات کاربر. پایین بودن سرعت پاسخگویی، مثلا هنگامی که یک component را touch می کنید و باید کمی صبر کنید تا پاسخ بگیرید، قابل مشاهده است.
در ری اکت Blank areas: وقتی VirtualizedList نمی تواند آیتم ها را با سرعت کافی render کند، ممکن است بخشی از لیست به جای آیتم ها، فضایی سفید به کاربر نشان داده شود.
در ری اکت Viewport: فضای قابل رویت از محتوا، حاوی pixel های render شده
در ری اکت Window: فضایی که آیتم ها باید در آن load شوند، که عمدتا از Viewport بزرگتر است.
در ری اکت Props
در اینجا لیستی از props ها را می بینید که می توانید از آن ها برای بهبود عملکرد FlatList استفاده کنید:
RemoveClippedSubviews
اگر مقدار آن true باشد، viewهای بیرون از viewport را حذف می کند.
مزایا: این کار زمان صرف شده روی thread اصلی را کم می کند، و در نتیجه با حذف viewهای خارج از viewport احتمال drop شدن frame ها را کم می کند.
معایب: این پیاده سازی ممکن است bug داشته باشد. مثلا محتوایی از دست برود (بیشتر در iOS مشاهده شده)، به خصوص زمانی که کارهای پیچیده ای با transforms ها یا absolute positioning انجام می دهید. برای صرفه جویی در مصرف memory هم چندان کاربرد ندارد، چرا که viewها فقط detach می شوند.
MaxToRenderPerBatch
این یک prop مختص VirtualizedList است که می تواند توسط FlatList مقداردهی شود. مقدار آیتم های render شده در هر scroll را تعیین می کند.
مزایا: تعیین یک عدد بزرگتر به معنای کم شدن فضای خالی هنگام scroll کردن خواهد بود.
معایب: آیتم بیشتر به ازای هر scroll زمان بیشتری برای اجرای کد جاوااسکریپت می گیرد و احتمال block شدن پردازش eventهای دیگر هست و سرعت پاسخگویی را کم می کند.
UpdateCellsBatchingPeriod
مقدار این property تعیین کننده ی تاخیر به میلی ثانیه بین render کردن دیتا در هر scroll است.
مزایا: استفاده از این property در کنار maxToRenderPerBatchبرای مثال این امکان را می دهد که آیتم های بیشتر با scrollکمتر، یا آیتم های کمتر در scroll های بیشتر، داشته باشیم.
معایب: تاخیر بین render شدن دیتا در هر scroll ممکن است باعث ایجاد فضای خالی شود، تاخیر کمتر ممکن است موجب کاهش سرعت پاسخگویی applicationشود.
InitialNumToRender
مقدار اولیه آیتم ها برای render شدن را معین می کند.
مزایا: تعداد آیتم های load شده را در صفحه تمام device ها معین می کند. این ممکن است بشدت روی بهبود عملکرد application هنگام render شدن برای اولین بار، تاثیر بگذارد.
معایب: در نظر گرفتن مقدار کمی برای initialNumToRender ممکن است باعث بوجود آمدن فضای خالی شود، به ویژه اگر عدد به قدری کم باشد که viewport را در هنگام render شدن اولیه، پر نکند.
windowSize
این عدد یک واحد اندازه گیری است، که در آن 1 معادل height viewport شماست. مقدار پیش فرض آن 21 است (10 برابر viewport از بالا، 10 برابر آن از پایین و یکی برای وسط).
مزایا: مقدار بزرگتر برای windowSize احتمال دیدن فضای خالی هنگام scroll را کم می کند. درمقابل، مقدار کمتر در مصرف memory صرفه جویی می کند، چرا که تعداد آیتم هایی که همزمان load می شوند، کم می شود.
معایب: بزرگ شدن windowSize به مصرف بیشتر memory منتج می شود و کوچکتر شدن آن احتمال دیدن فضای خالی را بیشتر می کند.
LegacyImplementation
این property، FlatList را مجبور می کند از پیاده سازی قدیمی و منسوخ شده ی ListView به جای VirtualizedList استفاده کند.
مزایا: مشکل فضای خالی و bug های VirtualizedList نخواهید داشت.
معایب: مصرف memory بیشتر و احتمال توقف ناگهانی application هنگام استفاده از لیست های بزرگ با آیتم های پیچیده بیشتر می شود. از قابلیت های زیادی پشتیبانی نمی شود و ممکن است به دلیل منسوخ شدنش، bug های بیشتر هم داشته باشد.
لیست List item ها
در این بخش نکاتی درمورد component های list item مطرح شده است. List item ها هسته اصلی لیست ها هستند، و عملکردشان اهمیت زیادی دارد.
از component های ساده استفاده کنید.
هرچه component هایتان پیچیده تر باشد، سرعت render کمتری دارند. از روال های منطقی پیچیده و آیتم های تودرتو در لیست استفاده نکنید. اگر از لیست در قسمت های مختلف application استفاده می کنید، یک component برای لیست بزرگتان درست کنید و تاحد ممکن منطق و تودرتویی را در آن به حداقل برسانید.
از component های سبک استفاده کنید
هرچه component هایتان سنگین تر باشند، سرعت render شدنشان پایین می آید. از عکس های سنگین استفاده نکنید (از thumbnail عکس یا نسخه crop شده آن استفاده کنید). تا جایی که ممکن است effect ها و تعاملات و اطلاعات درون لیست را کم کنید. آیتم ها را بعدا می توانید با هرمقدار جزئیات که می خواهید به طور مستقل نمایش دهید.
از shouldComponentUpdate استفاده کنید
در React، PureComponent خودش یک تابع shouldComponentUpdate با پیاده سازی ساده ای درحد یک مقایسه، دارد. این تابع هزینه بر است چرا که همه ی props ها را چک می کند. اگر تابعی با عملکرد بهتر می خواهید، طوری آن را پیاده سازی کنید که فقط props هایی که احتمالا تغییر کرده اند را، چک کند. اگر لیست ساده پیاده سازی شده باشد حتی می توانید از قطعه کدی مثل کد زیر استفاده کنید:
shouldComponentUpdate() {
return false
}
از عکس های بهینه شده cache شده استفاده کنید
برای بهبود عملکرد برنامه حین کار با عکس ها، می توانید از package هایی مثل react-native-fast-image که توسط DylanVann@ توسعه داده شده، استفاده کنید. هر عکس در لیست یک instance از new Image() است. هرچه سریعتر عکس به loaded hook برسد، Thread جاوااسکریپت مختص آن سریعتر آزاد می شود.
از getItemLayout استفاده کنید
اگر تمام component های مربوط به آیتم های درون لیست height یکسانی دارند، (یا width یکسان برای لیست های افقی) استفاده از این prop، FlatList را از قید محاسبه های async مربوط به layout، آزاد کند.
این روش خوبی برای بهبود عملکرد است.
اگر component ها سایز متفاوت دارند و باز هم می خواهید performance خوبی داشته باشید، طراحی خود را تغییر دهید.
از keyExtractor یا key استفاده کنید
برای FlatList خود از keyExtractor استفاده کنید. این prop برای caching استفاده می شود و به عنوان نوعی کلید برای نگه داری ترتیب آیتم ها استفاده می شود. همچین می توانید از یکprop key درون آیتم ها استفاده کنید.
از anonymous function در renderItem استفاده نکنید
تابع renderItem را بیرون تابع render بگذارید، به این شیوه از بازسازی اش در هربار render شدن جلوگیری کرده اید.
renderItem = ({ item }) => (<View key={item.key}><Text>{item.title}</Text></View>);
render(){
// ...
<FlatList
data={items}
renderItem={renderItem}
/>
// ...
}