آموزش React native-قسمت هفتم

بخش اول آموزش React Nativeسلام در بخش ششم آموزش React Native استفاده از Fetch , Web Socket, کتابخانه های معروف ,تنظیماتی برای بهبود عملکرد Flat list و لیست List item ها در React Native را یاد گرفتیم . حال با بخش ششم با ما همراه باشید:کامپوننت ها Component ها و API ها در React Native:ری اکت React Native چندین component built-in دارد. لیست کاملی از component ها و API ها در این سایت موجود است. اگر نمی دانید از کجا شروع کنید، یکی از دسته بندی های زیر مناسب است:· کامپوننت های component های پایه· رابط کاربری User Interface· لیست List View ها· کامپوننت component های اختصاصی iOS· کامپوننت component های اختصاصی android· کامپوننت component های دیگرآموزش React Nativeالبته شما محدود به component ها و API های React Native نیستید. React Native جامعه ای از توسعه دهندگان است. اگر دنبال کتابخانه ای با کاربردی مشخص می گردید، می توانید npm registry را برای package های React Native نگاه کنید. و یا نگاهی به Awesome React Native بیندازید.کامپوننت component های پایهاغلب application ها از یکی از این component ها استفاده می کنند. اگر تازه با React Native آشنا شده اید، بهتر است با آن ها آشنا شوید.چشم انداز View: اساسی ترین component برای ساخت یک UIمتن Text: component برای نمایش متنعکس Image: component برای نمایش عکسورودی متن TextInput: component برای دریافت متن از طریق keyboardاسکرول ScrollView: یک container با قابلیت scroll که می تواند چندین View و component را درخود نگه دارد.استایل StyleSheet: یک لایه انتزاعی مشابه stylesheet های CSSUser Interfaceاز طریق این component ها می توان المان های کنترلی را render کرد.دکمه Button: یک component پایه ی button برای دریافت تعاملات کاربر از طریق touch صفحهجمع کننده Picker: یک component Picker native در iOS و androidاسلایدر Slider: component برای انتخاب یک مقدار از بین بازه ای از مقادیرسوییچ Switch: برای دریافت ورودی های BooleanList View هابرخلاف ScrollView، این component ها فقط المان هایی که در لحظه در صفحه نمایش داده می شود را render می کنند و برای لیست هایی با دیتای زیاد مناسب هستند.فلت FlatList: component با قابلیت scroll برای نمایش لیستلیست SectionList: مشابه FlatList با امکان بخش بندی لیست و افزودن تیتر به هر بخشکامپوننت component ها و API های ویژه iOSاغلب این component ها در حقیقت به عنوان wrapper برای کلاس های رایج UIKit عمل می کنند.اکشن ActionSheetIOS: برای نمایش یک action sheet یا share sheetآلرت AlertIOS: یک alert dialog به همراه پیام یا یک notification برای دریافت ورودی از کاربردیت DatePickerIOS: یک date/time picker (selector) برای iOS render می کند.عکس ImagePickerIOS: یک image picker برای iOS render می کند.پیمایش NavigatorIOS: یک wrapper برای کلاس UINavigationController، که می توانید با آن یک navigation stack بسازید.پیشرفت ProgressViewIOS: یک UIProgressView برای iOS render می کند.پوش PushNotificationIOS: notification ها، شامل مدیریت مجوزها و icon badge number، را برای application مدیریت می کند.سگمنت SegmentedControlIOS: یک UISegmentedControl برای iOS render می کند.TabBarIOS:یک UITabViewController را برای iOS render می کند. به همراه TabBarIOS.Item استفاده شود.کامپوننت ها component ها و API های ویژه androidاغلب این component ها در حقیقت به عنوان wrapper برای کلاس های رایج androidعمل می کنند.BackHandler:دکمه سخت افزاری بازگشت را شناسایی می کند.DatePickerAndroid:یک date picker استاندارد android را باز می کند.DrawerLayoutAndroid:یک DrawerLayout android را render می کند.PermissionsAndroid:امکان کار با مدل permission های معرفی شده در Android M را می دهد.ProgressBarAndroid:یک ProgressBar android را render می کند.TimePickerAndroid:یک time picker استاندارد android باز می کند.ToastAndroid:یک notification Toast android می سازد.ToolbarAndroid:یک Toolbar android را render میکند.ViewPagerAndroid:یک container برای حرکت به چپ و راست بین child view هاکامپوننت component های دیگراین component ها برای کاربردهای خاصی استفاده می شوند. برای لیست کامل component ها و API ها، بخش مربوطه را ببینید.ActivityIndicator:یک نشانگر دایره ای برای loading نمایش می دهد.Alert:یک صفحه هشدار با تیتر و متن خاص نمایش می دهد.Animated:کتابخانه ای برای ایجاد انیمیشن که براحتی قابل ساخت و استفاده هستندClipboard:واسطی برای دریافت و مقداردهی به محتوای clipboard در android و iOSDimensions:واسطی برای دریافت ابعاد deviceKeyboardAvoidingView:یک view که به صورت خودکار در صورت وجود keyboard مجازی، کنار می رود.Linking:یک واسط کلی برای کار با link هایی که به application وارد می شوند و یا link هایی که از application خارج می شود.Modal:روشی برای نمایش محتوا روی یک viewPixelRatio:امکان دسترسی به pixel density device را می دهد.RefreshControl:این component درون یک ScrollView استفاده می شود.StatusBar:کامپوننت component برای کنترل status bar applicationWebView:کامپوننت component که محتوای تحت وب را درون یک view native نمایش می دهد.آموزش React Nativeکدهای پلتفرم - محور برای React Native Appsهنگام ساخت یک application که روی پلتفرم های مختلف قابلیت اجرا دارد، می خواهیم تا جایی که ممکن است از کدهای یکسان در بخش های مختلف بارها استفاده کنیم. با این حال، سناریوهای زیادی ممکن است پیش بیاید که در آن کدها باید متفاوت باشند، برای مثال ممکن است بخواهیم المان های بصری متفاوتی برای application android و iOS خود استفاده کنیم.ری اکت React Native دو روش برای سازماندهی به کد و جدا کردن آن براساس پلتفرم در اختیار می گذارد:· استفاده از Platform module· استفاده از platform-specific file extensionsبعضی component ها ممکن است ویژگی هایی داشته باشند که فقط روی یک پلتفرم کار کند. همه این ویژگی ها با @platform نشانه گذاری شده اند.ری اکت React Native ماژولی در اختیار می گذارد که پلتفرمی که application در آن درحال اجراست را، شناسایی می کند. می توانید از این منطق برای نوشتن کدهای پلتفرم - محور خود استفاده کنید. این روش را فقط زمانی بکار ببرید که بخش کوچکی از component پلتفرم - محور است.import {Platform, StyleSheet} from 'react-native';const styles = StyleSheet.create({height: Platform.OS === 'ios' ? 200 : 100,});هنگام اجرای application روی iOS، Platform.OS برابر ios خواهد بود و هنگام اجرا روی android برابر android خواهد بود.همچنین یک متد Platform.select هم موجود است، که اگر object حاوی Platform.OS ، به عنوان ورودی به آن بدهیم، مقداری را برمی گرداند که مختص پلتفرمی است که کد روی آن درحال اجراست.import {Platform, StyleSheet} from 'react-native';const styles = StyleSheet.create({container: {flex: 1,...Platform.select({ios: {backgroundColor: 'red',},android: {backgroundColor: 'blue',},}),},});نتیجه ی این کد یک container است که روی هر دو پلتفرم flex: 1 دارد، و روی iOS یک background قرمز، و روی application یک background آبی خواهد داشت.از آنجا که هر مقداری می گیرد، می توانید از آن برای برگرداندن component هم استفاده کنید، برای مثال:const Component = Platform.select({ios: () => require('ComponentIOS'),android: () => require('ComponentAndroid'),})();<Component />;تشخیص version applicationدر application، ماژول Platform میتواند برای شناسایی نسخه android که application روی آن درحال اجراست، استفاده شود.import {Platform} from 'react-native';if (Platform.Version === 25) {console.log('Running on Nougat!');}تشخیص version iOSدر iOS، Version خروجی -[UIDevice systemVersion] است، که رشته ای حاوی version فعلی OS آن است. یک نمونه از version سیستم "10.3" است. برای مثال، برای تشخیص major version number در iOS:import {Platform} from 'react-native';const majorVersionIOS = parseInt(Platform.Version, 10);if (majorVersionIOS <= 9) {console.log('Work around a change in behavior');}Platform-specific extensionsوقتی کد پلتفرم - محور پیچیده ای دارید، بهتر است کدها را در فایل های جداگانه بگذارید. React Native فایل های با پسوند .ios. و .android. را تشخیص می دهد و هنگام نیاز، آن ها را در پلتفرم مختص خودشان load می کند.برای مثال، فرضا دو فایل زیر را در پروژه خود دارید:BigButton.ios.jsBigButton.android.jsمی توانید component را به صورت زیر به کار ببرید:import BigButton from './BigButton';ری اکت React Native به صورت اتوماتیک براساس پلتفرمی که کد روی آن درحال اجراست، فایل مناسب را استفاده می کند.نیتیو Native-specific extensions (اشتراک کد با NodeJS و وب)هنگامی که می خواهید یک ماژول بین NodeJs/Web و React Native مشترکا استفاده شود، اما درمورد Android/iOS بودن پلتفرم حساسیتی ندارید، می توانید از پسوند .native.js استفاده کنید. این مورد بخصوص هنگامی کاربرد دارد که پروژه ای کد مشترک بین React Native و ReactJS دارد.برای مثال، فایل های زیر را در پروژه ای دارید:Container.js # picked up by Webpack, Rollup or any other Web bundlerContainer.native.js # picked up by the React Native bundler for both Android and iOS (Metro)می توانید همچنان آن را بدون پسوند .native، اصطلاحا require کنید:import Container from './Container';نکته :برای اینکه از داشتن کدهای بی استفاده در فاز تولید پروژه جلوگیری کنید، Web bundler خود را به گونه ای config کنید که پسوند .native.js را نادیده بگیرد. این کار موجب کاهش سایز bundle نیز می شود.حرکت بین صفحات (Navigation) در React Nativeاپلیکیشن application های موبایل معمولا تک صفحه ای نیستند. مدیریت نمایش و حرکت بین چندین صفحه معمولا توسط navigator انجام می شود.این بخش آموزش، component های موجود در React Native، که مناسب این کار را بررسی می کند. اگر تازه با این مبحث آشنا شده اید، بهتر است از کتابخانه ی React Navigation استفاده کنید. این کتابخانه راه حل ساده ای ارائه می دهد، و هردو شیوه ی stack navigation و tabbed navigation را در هردو سیستم عامل android و iOS پشتیبانی می کند.اگر می خواهید application تان شبیه یک native application ها به نظر برسد، یا می خواهید React Native را به یک application که به صورت native حرکت بین صفحات را مدیریت می کند، اضافه کنید، کتابخانه ی react-native-navigation مناسب کار شماست.React Navigationراه حل رایج بین توسعه دهندگان React، کتابخانه ی مستقل React Navigation است که به توسعه دهندگان امکان راه اندازی چندین صفحه در app با چند خط کد را می دهد.گام اول نصب این کتابخانه در پروژه است:npm install --save react-navigationگام دوم نصب react-native-gesture-handler است:yarn add react-native-gesture-handler# or with npm# npm install --save react-native-gesture-handlerحال باید react-native را به react-native-gesture-handler ارتباط دهیم:react-native link react-native-gesture-handlerسپس میتوانیم به راحتی یک application با یک صفحه Home، و یک صفحه profile بسازیم:import {createStackNavigator, createAppContainer} from 'react-navigation';const MainNavigator = createStackNavigator({Home: {screen: HomeScreen},Profile: {screen: ProfileScreen},});const App = createAppContainer(MainNavigator);export default App;هر component صفحه می تواند navigation options هایی مثل title برای عنوان صفحه، set کند. می تواند روی navigation prop رویدادهایی استفاده کند که صفحه را به صفحات دیگر ارتباط دهد:class HomeScreen extends React.Component {static navigationOptions = {title: 'Welcome',};render() {const {navigate} = this.props.navigation;return (<Buttontitle="Go to Jane's profile"onPress={() => navigate('Profile', {name: 'Jane'})}/>);}}آموزش React Nativeبا وجود React Navigation router ها، تغییر در الگوی حرکات کار آسانی است. از آنجا که router ها می توانند درون هم قرار بگیرند، می توانید الگوی حرکات را برای قسمتی از application تغییر دهید بدون اینکه کل آن تغییر کند.چشم انداز viewها در کتابخانه React Navigation از component های native و کتابخانه ی Animated برای ارائه ی انمیشن های fps 60 استفاده می کنند. بعلاوه، انیمیشن ها و حرکات به راحتی می تواند به شکل مورد نظر شما، سفارشی شود.برای مطالعه کامل درمورد React Navigation، این لینک را بیبنید و یا سری به مستندات دیگر مثل مقدمه ای بر Navigator ها، بزنید.تصاویر در React Nativeتصاویر با Resource ثابتری اکت React Native روشی یکپارچه برای مدیریت عکس ها و دیگر فایل های media در application android و iOS فراهم می آورد. برای افرودن یک عکس ثابت به application، آن را جایی در کنار فایل source code بگذارید و به شکل زیر به آن دسترسی پیدا کنید:<Image source={require('./my-icon.png')} />نام عکس به شیوه ای مشابه ماژول های جاوااسکریپت، resolve می شود. در مثال بالا، packager در پوشه ی آن component که می خواهد به آن دسترسی پیدا کند ( و آن را require کرده) به دنبال my-icon.png می گردد. همچنین اگر فایل های icon.ios.png و my-icon.android.png داشته باشید، فایل مناسب پلتفرم اجرایی را، انتخاب می کند.می توانید از پسوندهای @2x و @3x برای عکس های صفحات با تراکم پیکسلی (screen density) متفاوت، استفاده کنید. اگر ساختار فایلی مشابه زیر داشته باشید:.├── button.js└── img├── check.png├── check@2x.png└── check@3x.pngو یک کد button.js حاوی :<Image source={require('./img/check.png')} />پکیج Packager عکس مناسب با تراکم پیکسلی صفحه را، آماده نمایش می کند. برای مثال، فایل check@2x.png در یک iPhone 7 استفاده می شود، درحالی که فایل check@3x.png در iPhone 7 Plus یا Nexus 5 استفاده می شود. اگر عکسی مناسب تراکم پیکسلی صفحه موجود نباشد، بهترین گزینه ممکن انتخاب می شود.در Windows بهتر است پس از افزودن عکس های جدید به پروژه، packager را restart کنید.کار با عکس ها در React ویژگی های خوبی دارد:1. در iOS و android سیستم یکسانی دارد.2. عکس ها در همان پوشه ای قرار دارند که کد جاوااسکریپت هست. هر component مستقل و کافی است.3.گلوبال global namespace وجود ندارد، لازم نیست نگران یکسان بودن تصادفی نام عکس ها باشید.4. فقط عکس هایی که در واقعا لازم هستند، برای application آماده می شود.5. افزودن و تغییر عکس ها نیاز به compile دوباره ی application ندارد، فقط کافی است شبیه ساز را restart کنید.6. پکیجpackager ابعاد عکس را می داند، لازم نیست آن را در کد قرار دهید.7. عکس ها را می توان در package های npm توزیع کرد.برای اینکه این شیوه جواب بدهد نام عکس در require مقداری ثابت باشد:// GOOD<Image source={require('./my-icon.png')} />;// BADvar icon = this.props.active ? 'my-icon-active' : 'my-icon-inactive';<Image source={require('./' + icon + '.png')} />;// GOODvar icon = this.props.active? require('./my-icon-active.png'): require('./my-icon-inactive.png');<Image source={icon} />;توجه کنید که تصاویری که به این شیوه require می شوند، حاوی اطلاعات width و height تصویر هستند. اگر می خواهید عکس را پویا scale کنید ( توسط flex) باید دستی { width: undefined, height: undefined } را روی style attribute مقدار دهی کنید.منابع Resource های ثابت دیگر به غیر از تصویرنیاز syntax require که بالا نشان دادیم می تواند برای افزودن فایل صوتی، ویدئو و فایل های متنی در پروژه هم استفاده شود. انواع رایج فایل هایی که پشتیبانی می شوند عبارتند از html، mav، mp4، mov، و pdf. برای لیست کامل، این لینک را ببینید.می توانید پشتیبانی از انواع دیگر فایل را با افزودن assetExts resolver option به Metro configuration اضافه کنید.توجه کنید برای ویدئوها باید به جای flexGrow از absolute positioning استفاده کنید، چرا که اطلاعات مربوط به سایز فعلا برای resource های غیر از عکس، در دسترس نیست. این محدودیت برای ویدئوهایی که مستقیما به Xcode یا پوشه ی Assets در android، reference داده شده اند، وجود ندارد.تصاویر برای application های hybridاگر application hybrid دارید (به این معنا که بخشی از UI آن با React Native و بخشی از کد مختص android/iOS نوشته شده)، می توانید از عکس های آن ها استفاده کنید. برای عکس هایی که توسط Xcode asset catalogs یا پوشه ی drawable در android به application اضافه شده اند، نام عکس را بدون پسوند استفاده کنید :<Image source={{uri: 'app_icon'}} style={{width: 40, height: 40}} />برای عکس هایی که در پوشه ی assets android هستند، از الگوی asset:/ استفاده کنید. به عهده شماست که وجود عکس ها در application را تضمین کنید. بعلاوه ابعاد عکس را باید دستی تنظیم کنید.تصاویر از منابع موجود در شبکهبسیاری از عکس هایی که در application استفاده می کنید تا زمان کامپایل در دسترس نیستند، و یا ممکن است بخواهید برای پایین نگه داشتن حجم فایل اجرایی، آن ها را dynamic به application اضافه کنید. برخلاف عکسهای resource ثابت، باید دستی ابعاد عکس را مشخص کنید. توصیه می شود به دلیل محدودیت App Transport Security مخصوص iOS، از https استفاده کنید.// GOOD<Image source={{uri: 'https://facebook.github.io/react/logo-og.png'}}style={{width: 400, height: 400}} />// BAD<Image source={{uri: 'https://facebook.github.io/react/logo-og.png'}} />درخواست request برای تصویراگر مایلید همراه request برای تصویر، HTTP-Verb، Header یا Body تعیین کنید، می توانید آن ها را بصورت property روی object source تعریف کنید:<Imagesource={{uri: 'https://facebook.github.io/react/logo-og.png',method: 'POST',headers: {Pragma: 'no-cache',},body: 'Your Body goes here',}}style={{width: 400, height: 400}}/>آموزش React Nativeعکس های بصورت داده در Uriممکن است تصویر را به صورت دیتایی encode شده از REST API بگیرید. می توانید برای استفاده از این تصاویر از الگوی 'iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg==',}}/>کنترل Cache Control (مخصوص iOS)گاهی فقط می خواهیم اگر عکس در local cache موجود است، آن را نمایش دهیم. برای مثال، می خواهیم تا زمانی که تصویر با resolution بالا موجود نیست، یک عکس با resolution پایین load کنیم. گاهی می خواهیم عکس update نشده را نشان دهیم تا در پهنای باند صرفه جویی شود. property cache در source، امکان مدیریت تعامل بین شبکه و Cacheرا میدهد.default:استراتژی پیش فرض پلتفرم native (android/iOS ) را استفاده می کند.reload:دیتا از source address دریافت می شود و از cache استفاده نمی شود.force-cache:دیتای cache شده ی موجود استفاده می شود، بدون توجه عمر آن یا expiration date آن.only-if-cached:دیتای cache شده ی موجود استفاده می شود، بدون توجه عمر آن یا expiration date آن. اگر دیتایی مرتبط با request در cache موجود نباشد، تلاشی برای دریافت دیتا از شبکه نخواهد شد.<Imagesource={{uri: 'https://facebook.github.io/react/logo-og.png',cache: 'only-if-cached',}}style={{width: 400, height: 400}}/>عکس های درون Local Filesystemبخش CameraRoll را برای مثالی از استفاده از local resource هایی که خارج از Images.xcassets هستند، ببینید.آیiOS چندین سایز برای یک عکس در دوربین ذخیره می کند، برای performance بهتر، انتخاب کوچکترین عکس ها اهمیت دارد. وقتی می خواهید یک thumbnail در سایز X200200 استفاده کنی، نباید از عکسی با کیفیت بالای 3264x2448 به عنوان source استفاده کنید. اگر مورد کاملا مناسب برای آن باشد، React Native آن را برمی دارد. در غیر این صورت عکسی را انتخاب میک ند که حداقل 50 درصد بزرگتر است تا هنگام کوچک شدن، تار نشود. همه ی این موارد خودکار انجام می شود بدون اینکه لازم باشد یک خط کد برای آن بنویسید.چرا سایز همه چیز را اتوماتیک تعیین نکنیم؟در مرورگر اگر به عکسی سایز دقیق ندهید، یک المان 0x0 ، render می شود، عکس دانلود می شود و سپس عکس با سایز درست render می شود. بزرگترین مشکل این شیوه، این است که UI در طول load عکس ها دائم تغییر می کند که تجربه کاربری خوبی نیست.در React Native این رفتار عمدا پیاده سازی نشده است. کار توسعه دهندگان بیشتر می شود چرا که باید ابعاد عکسی را که قرار است load شود بدانند، ولی تجربه کاربری را بهبود می بخشد. عکس های static که توسط دستور require('./my-icon.png') ،load می شوند می توانند اتوماتیک اندازه دهی شوند، چرا که ابعادشان به محض load در دسترس است.برای مثال، نتیجه ی اجرایrequire('./my-icon.png') می تواند این باشد:{"__packager_asset":true,"uri":"my-icon.png","width":591,"height":573}منابع Source به عنوان یک objectدر React Native، src در واقع source نامیده شده و یک string نمی پذیرد، بلکه یک object با property uri می پذیرد.<Image source={{uri: 'something.jpg'}} />از دیدگاه زیرساختی، این پیاده سازی به ما اجازه می دهد به این object، metadata اضافه کنیم. برای مثال هنگامی که از require('./my-icon.png') استفاده می کنید، اطلاعاتی درمورد مکان دقیق و سایز آن به object اضافه می شود. این رویه برای پیاده سازی های بعدی هم خوب است، برای مثال ممکن است بخواهیم از sprite پشتیبانی کنیم، به جای {uri: ...} می توانیم {uri: ..., crop: {left: 10, top: 50, width: 20, height: 40}} داشته باشیم.سمت کاربر، امکان افزودن مقادیری برای ابعاد سایز وجود خواهد داشت. همچنین می توانید از هر data structure دیگری برای نگه داری اطلاعات درمورد تصاویرتان استفاده کنید.عکس background با Nestingیک قابلیت که همواره توسعه دهنگان سمت وب خواهان آن بوده اند، تصویر پس زمینه است. برای این کار، می توانید از component <ImageBackground> استفاده کنید، که prop هایی مشابه component <Image> دارد، ومی توانید هرالمانی به عنوان child به آن اضافه کنید، که روی آن نمایش داده شود.ممکن است در مواردی نخواهید از <ImageBackground> استفاده کنید، چرا که پیاده سازی آن بسیار ساده است. می توانید برای ساخت component سفارشی برای هدف مورد نظر خود، به مستندات مربوط به آن مراجعه کنید.return (<ImageBackground source={...} style={{width: '100%', height: '100%'}}><Text>Inside</Text></ImageBackground>);توجه کنید تعیین style هایی چون width و height اجباری است.iOS Border Radius Stylesاین property ها که برای style دهی به حاشیه component ها استفاده می شود فعلا در component image برای iOS، کار نمی کند:· borderTopLeftRadius· borderTopRightRadius· borderBottomLeftRadius· borderBottomRightRadiusفرایند decoding روی thread غیر از main threadدکود decode کردن عکس ها زمان بر است. یکی از دلایل اساسی از دست رفتن فریم ها در وب این است که فرایند decoding روی thread اصلی انجام می شود. در React Native، این فرایند در thread دیگری انجام می شود. در عمل، باید راهکارهایی برای نمایش جایگزینی برای عکسی که درحال دانلود شدن است، پیاده سازی کنید. نمایش یک placeholder درحالی که عکس درحال decode شدن است ساده است و تغییر زیادی در کد نمی خواهد.پایان بخش هفتم آموزش React Nativeبا ادامه آموزش هشتم همراه با باشید