<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های عظیم عاطفی</title>
        <link>https://virgool.io/feed/@atefiazim1997</link>
        <description>یک عدد عظیم عاطفی هستم دانشجوی سال آخر کامپیوتر , عاشق کامپیوتر و بازی ها شوتر . کمی عجولم و دوس دارم همه چی رو خیلی سریع یاد بگیرم و درست کنم .  https://www.linkedin.com/in/azimatefi</description>
        <language>fa</language>
        <pubDate>2026-04-15 01:19:04</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/42716/avatar/m6ukks.png?height=120&amp;width=120</url>
            <title>عظیم عاطفی</title>
            <link>https://virgool.io/@atefiazim1997</link>
        </image>

                    <item>
                <title>درک راحت تر dynamic imports در React قسمت دوم</title>
                <link>https://virgool.io/iran-react-community/%D8%AF%D8%B1%DA%A9-%D8%B1%D8%A7%D8%AD%D8%AA-%D8%AA%D8%B1-dynamic-imports-%D8%AF%D8%B1-react-%D9%82%D8%B3%D9%85%D8%AA-%D8%AF%D9%88%D9%85-wd199jguhvhh</link>
                <description>خب بعد اینکه مفهوم اولیه dynamic import رو فهمیدم (لینک قسمت اول) نیاز داریم که بتونیم اون رو داخل React پیاده سازی کنیم روش اولی که قراره امروز استفاده کنیم روش راحت تری نسبت به روش دوم هست برای اینکه بتونیم کار رو راحت شروع کنیم اول از همه با CRA یه پروژه رو ایجاد می کنیم تا بتونیم سفرمون به اعماق dynamic import آغاز کنیم .npx create-react-app reactdynamicimportبعد از اینکه پروژمون ایجاد شد فایل src/app.js رو باز می کنیم و کاستوم می کنیم.function App() {
    const [component, setComponent] = React.useState(&quot;i am initial text&quot;);
    return (
        &lt;div className=&quot;App&quot;&gt;
            &lt;header className=&quot;App-header&quot;&gt;
                &lt;img src={logo} className=&quot;App-logo&quot; alt=&quot;logo&quot; /&gt;
                {component}
           &lt;/header&gt;
        &lt;/div&gt;
        );
 }
 export default App;خب حالا صفحه ای که لود میشه به صورت زیر خروجی دارهخب حالا پوشه src/comps رو ایجاد می کنیم و دو فایل persian.js و english.js رو ایجاد می کنیم که محتوای این دو فایل // english.js
export default (text = &quot;I&#039;m English Boiiiiiiii&quot;) =&gt; &lt;p&gt;{text}&lt;/p&gt;;
// persian.js
export default (text = &quot;زبان مادری ما فارسی است&quot;) =&gt; &lt;p&gt;{text}&lt;/p&gt;;از اونجایی که CRA به صورت پیش فرض import() رو داخل خودش جا داده توی این قسمت از اون استفاده می کنیم .خب حالا دو تابع برای فراخوانی فارسی و انگلیسی داریم . const loadpresian = () =&gt; {
    import(&quot;./comps/persian&quot;)
        .then(persian =&gt; {
            setComponent(persian.default());
        })
        .catch(err =&gt; {
            // Handle failure
        });
};
const loadenglish = () =&gt; {
     import(&quot;./comps/english&quot;)
         .then(english =&gt; {
             setComponent(english.default());
          })        
           .catch(err =&gt; { 
               // Handle failure
            }); 
};


خب همونجوری که میبینیم این دوتابع زمانی که فراخوانی میشن به صورت خیلی خفن و باحال سعی میکنن فایل js جدید رو import کنن و اگر موفق بشن ما متن داخل اون رو با متن داخل state خودمون عوض می کنیم . حالا کافیه دو دکمه هم به صفحه اضافه کنیم خب حالا بیایم تست کنیم ببینیم چه اتفاقی افتاد.&lt;button ={loadpresian}&gt;فارسی&lt;/button&gt; 
&lt;button ={loadenglish}&gt;english&lt;/button&gt;خب حالا زمانی که دکمه فارسی رو میزنیم اتفاقی که میوفته اینه که ما میبینیم یه درخواست جدید ثبت می شه که این همون import خودمونه به تصویر زیر توجه کنید!خب حالا ده بارم که دیگه روی دکمه فارسی کلیک کنیم می بینیم که درخواست برای فایل جدیدی ثبت نمیشه یعنی هر فایل یه بار می تونه import بشه از اون به بعد دیگه توی صفحمون موجوده حالا دکمه English رو میزنیم.خب حالا میبینیم که باز هم همون اتفاق بالا افتاد :))) و ما به حالتی خیلی خفن تا زمانی که به یک فایل نیاز پیدا نکنیم اون رو اضافه نمی کنیم . در قسمت آتی دیگه خبری از آماده بودن همه چیز نیست و میخوایم یه سری چیز ها رو خودمون کانفیگ کنیم و به مفهوم Code Splitting هم پی ببریم پس همراه من باشید. </description>
                <category>عظیم عاطفی</category>
                <author>عظیم عاطفی</author>
                <pubDate>Wed, 24 Jul 2019 07:54:39 +0430</pubDate>
            </item>
                    <item>
                <title>درک راحت تر dynamic imports در React قسمت اول</title>
                <link>https://virgool.io/@atefiazim1997/%D8%AF%D8%B1%DA%A9-%D8%B1%D8%A7%D8%AD%D8%AA-%D8%AA%D8%B1-dynamic-imports-%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84-gkovvxqdyntu</link>
                <description>خب بهتره اول از اینکه اصلا بریم غرق بشیم توی اصل مطلب بیایم با هم درک کنیم که dynamic imports یعنی چی و چرا باید از اون استفاده کنیم؟خب اول از همه باید بگم که به صورت پیش فرض الان دستور import به صورت یه دونه اعلان ثابت(static declarations) هست خب این یعنی چی؟ در اصل ما یه آدرس که از جنس رشته هست رو بهش می دیم که بهش می گیم فلان ماژول رو از فلان جا برام بیارش خب چیزی که اینجا جالبه اینه که عملا عملیات linking و binding اون ماژول با فایل فعلی ما در زمان اجرا اتفاق نمی وفته و قبلش اتفاق میوفته یعنی همون زمانی که ما فایلمون رو لود می کنیم اون ماژول هم لود میشه نه زمانی که از اون ماژول توی صفحه استفاده می کنیم . حالا می خوام بگم که شما فرض کن 100 تا ماژول 10kbداری توی صفحه که اگه دقت کنی یعنی 1mb همون اول کار لود میشه به نظرم من که چیز بدیه به نظر شما چطور؟خب تا اینجای کار فهمیدیم که عملیات فعلی import چجوری اتفاق میوفته و یه نمونه از مشکلی که می تونه برای ما هم به وجود بیاره رو هم مثال زدیم.البته بگم که یه جاهایی هم بدردمون میخوره مخصوصا وقتی بخوایم همه چیز رو یک جا باندل کنیم که آفلاین کار کنه .خب حالا بیاین با هم به این فکر کنیم که ما می تونه اون ماژول مورد نظر خودمون رو زمان اجرا اضافه کنیم به جای اینکه قبل زمان اجرا باشه (حس می کنم یکم فارسی هاش اذیت میکنه runtime &amp; pre-runtime خب یکم بهتر شد.) و این می تونه این ندای امید بخش رو برسونه که ما صرفا زمانی یک ماژول رو import می کنیم که به کار آید. بزارید من یه مثال بزنم که همه چیز واضح تر بشه واسمون نظرتون چیه؟فرض کنیم ما دوتا فایل english.js و persian.js رو داریم. بدین صورت://perisan.js
export default persianText = () =&gt; { return { something } }//english.js
export default englishText = () =&gt; { return { something }}فرض کنید این دوتا فایل کلی چیزهای دیگه هم داخلشه (صرفا از قوه تخیل خودتون استفاده کنید.) به نظرتون نیازه که وقتی کاربر فارسی زبان داخل سایت هست فایل مربوط به کاربر انگلیسی زمان هم لود شده باشه؟و در این جاست که به dynamic import نیاز مند میشیم. خب حالا استفاده از dynamic import میتونه به روش های مختلفی انجام بشه که توی قسمت بعدی این سری با هم بررسی می کنیم دو روشش رو سخت نگیرید زودی بهش می رسیم. راستی اگه خوشتون اومد و منتظر سری بعدی هم هستید توییتر منو می تونید فالو کنید تا زودتر مطلع بشید ازش ممنون که وقت گذاشتید!لینک قسمت دومhttps://twitter.com/azimat13</description>
                <category>عظیم عاطفی</category>
                <author>عظیم عاطفی</author>
                <pubDate>Fri, 19 Jul 2019 02:38:09 +0430</pubDate>
            </item>
                    <item>
                <title>شخصی سازی TabBar در ReactNavigation  قسمت اول</title>
                <link>https://virgool.io/@atefiazim1997/%D8%B4%D8%AE%D8%B5%DB%8C-%D8%B3%D8%A7%D8%B2%DB%8C-tabbar-%D8%AF%D8%B1-reactnavigation-%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84-liugrokp0ie5</link>
                <description>خب در ابتدا یه پروژه با استفاده از Expo میسازیم اگه تا حالا از Expo استفاده نکردید با دستور زیر راحت میتونید نصبش کنید و پروژه جدید رو بسازید !npm install expo-cli --global
expo init AnimatedTabBar
cd AnimatedTabBarخب حالا پروژه جدیدمون ساخته شده یادتون نره نوع پروژه Expo رو Blank نزارید تا با هم پیش بریم :)tabs          several example screens and tabs using react-navigationبعد از این که پروژمون ساخته شد . پیکیج react-native-animatable رو هم نصبش می کنیم که یکم کارای انیمیشن رو برامون راحت تر کنه .پروژه ساخته شده با Expoخب حالا به داخل پوشه navigation میریم و فایل MainTabNavigator.js که ساختار اصلی TabBar ما داخلشه رو باز می کنیم . در کنار این فایل یک فایل با نام TabBar رو می سازیم . خب داخل فایل TabBar مون به صورت زیر کد می زنیم که آیکون و متن شو به صورت کنار هم بزاره :)/* /src/components/TabBar.js */

import React from &quot;react&quot;;

import {
  View,
  StyleSheet,
  TouchableOpacity,
  Dimensions,
  Text
} from &quot;react-native&quot;;

const { width } = Dimensions.get(&quot;window&quot;);

const Styles = StyleSheet.create({
  container: { flexDirection: &quot;row&quot;, height: 52, elevation: 2 },
  tabButton: {
    flex: 1,
    justifyContent: &quot;space-around&quot;,
    alignItems: &quot;center&quot;,
    flexDirection: &quot;row-reverse&quot;
  },
  textStyle: {
    color: &quot;gray&quot;,
    fontSize: 13
  }
});

const TabBar = props =&gt; {
 const {
    renderIcon,
    getLabelText,
    activeTintColor,
    inactiveTintColor,
    onTabPress,
    onTabLongPress,
    getAccessibilityLabel,
    navigation
  } = props;

 const { routes, index: activeRouteIndex } = navigation.state;

 let type = &quot;slideInUp&quot;;

 return (
 &lt;View style={Styles.container}&gt;
 {routes.map((route, routeIndex) =&gt; {
 const isRouteActive = routeIndex === activeRouteIndex;
 const tintColor = isRouteActive ? activeTintColor : inactiveTintColor;
 return (
 &lt;TouchableOpacity
 key={routeIndex}
 style={[Styles.tabButton]}
 onPress={() =&gt; {
 onTabPress({ route });
            }}
 onLongPress={() =&gt; {
 onTabLongPress({ route });
            }}
 accessibilityLabel={getAccessibilityLabel({ route })}
 &gt;
 {isRouteActive ? (
 &lt;View style={Styles.tabButton}&gt;
 {renderIcon({ route, focused: isRouteActive, tintColor })}
                &lt;Text style={Styles.textStyle}&gt;{getLabelText({ route })}&lt;/Text&gt;
              &lt;/View&gt;
            ) : (
 &lt;View&gt;
 {renderIcon({ route, focused: isRouteActive, tintColor })}
              &lt;/View&gt;
            )}
          &lt;/TouchableOpacity&gt;
        );
      })}
    &lt;/View&gt;
  );
};

export default TabBar; خب حالا داخل فایل MainTabNavigator.js باید فایل TabBar رو Import کنیم .import TabBar from &quot;./TabBar&quot;;خب حالا باید کد زیر رو هم به createBottomTabNavigator مون اضافه کنیم تا کامپونت جدیدمون جایگزین کامپوننت دیفالت برای Tab Bar مون بشه .{ tabBarComponent: TabBar }بله حالا باید شکل تب بارمون عوض شده باشه به حالت زیر :خب حالا یکم به انیمیشن نیاز داریم تا تب بارمون کلی با حال بشه برای اینکار من می خوام روی تب فعالمون یک حالت overLay داشته باشم .&lt;Animated.View
 style={[
          StyleSheet.absoluteFill,
          {
            borderRadius: 25,
            backgroundColor: &quot;#c6c9ce&quot;,
            width: width / 3,
            height: 48,
            top: 2,
            opacity: 0.5
          }
        ]}
 /&gt;حالا من یه overlay خیلی نرم ساختم که اضافه اش می کنم به کد TabBar شخصی سازه شده خودمون ./* /src/components/TabBar.js */

import React from &quot;react&quot;;

import {
  View,
  StyleSheet,
  TouchableOpacity,
  Dimensions,
  Animated,
  Text
} from &quot;react-native&quot;;

const { width } = Dimensions.get(&quot;window&quot;);

const Styles = StyleSheet.create({
  container: { flexDirection: &quot;row&quot;, height: 52, elevation: 2 },
  tabButton: {
    flex: 1,
    justifyContent: &quot;space-around&quot;,
    alignItems: &quot;center&quot;,
    flexDirection: &quot;row-reverse&quot;
  },
  textStyle: {
    color: &quot;gray&quot;,
    fontSize: 13
  }
});

const TabBar = props =&gt; {
 const {
    renderIcon,
    getLabelText,
    activeTintColor,
    inactiveTintColor,
    onTabPress,
    onTabLongPress,
    getAccessibilityLabel,
    navigation
  } = props;

 const { routes, index: activeRouteIndex } = navigation.state;

 return (
 &lt;View style={Styles.container}&gt;
      &lt;Animated.View
 style={[
          StyleSheet.absoluteFill,
          {
            borderRadius: 25,
            backgroundColor: &quot;#c6c9ce&quot;,
            width: width / 3,
            height: 48,
            top: 2,
            opacity: 0.5
          }
        ]}
 /&gt;
 {routes.map((route, routeIndex) =&gt; {
 const isRouteActive = routeIndex === activeRouteIndex;
 const tintColor = isRouteActive ? activeTintColor : inactiveTintColor;
 return (
 &lt;TouchableOpacity
 key={routeIndex}
 style={[Styles.tabButton]}
 onPress={() =&gt; {
 onTabPress({ route });
            }}
 onLongPress={() =&gt; {
 onTabLongPress({ route });
            }}
 accessibilityLabel={getAccessibilityLabel({ route })}
 &gt;
 {isRouteActive ? (
 &lt;View style={Styles.tabButton}&gt;
 {renderIcon({ route, focused: isRouteActive, tintColor })}
                &lt;Text style={Styles.textStyle}&gt;{getLabelText({ route })}&lt;/Text&gt;
              &lt;/View&gt;
            ) : (
 &lt;View&gt;
 {renderIcon({ route, focused: isRouteActive, tintColor })}
              &lt;/View&gt;
            )}
          &lt;/TouchableOpacity&gt;
        );
      })}
    &lt;/View&gt;
  );
};

export default TabBar;

خب حالا یک OverLay خیلی نرم روی تب اول هست ولی خب با کلیک روی تب بعدی جا به جا نمیشه. خب حالا کافیه overlay خودمون رو وقتی یوزر کلیک می کنه روی تب دیگه ای رو جا به جا کنیم برای اینکار اول باید یه متغیر انیمیشن بسازیم مثل زیر که مقدار اولیش برابر با تب فعالمون هست (دلیلش رو دیگه خودتون حدس بزنید)let animationValue = new Animated.Value(activeRouteIndex);هم اکنون با استفاده از transform جذاب overlay رو میخوایم جا به جا کنیم به شکل زیر&lt;Animated.View
 style={[
          StyleSheet.absoluteFill,
          {
            borderRadius: 25,
            backgroundColor: &quot;#c6c9ce&quot;,
            width: width / 3,
            height: 48,
            top: 2,
            opacity: 0.5
          },
          {
            transform: [
              {
                translateX: animationValue.interpolate({
                  inputRange: [0, 1, 2],
                  outputRange: [0, width / 3, (width / 3) * 2]
                })
              }
            ]
          }
        ]}
 /&gt;خب حالا می بینیم که با هر بار کلیک روی تب جدید overlay مون میپره روی تب بعدی یعنی جا به جا نمیشه یجورایی خب سخت نگیرید کاری نداره که این بخاطر این مورد هست که با هر بار کلیک رو تب جدید کامپوننت دوباره رندر میشه برای این که این مشکل حل بشه باید قبل اینکه صفحمون جا به جا بشه overlay رو ببریم روی تب جدید و برای اینکه این عمل انجام بشه کافیه قبل عوض شدش route خودمون انیمیشن رو فراخوانی کنیم و مقدارشو از index تب قدیمی به index تب جدید با فاصله .5 ثانیه تغییر بدیم به شکل زیر یعنی به جای  /* onPress={() =&gt; {
    onTabPress({ route });
}} */باید کد زیر رو قرار بدیم .onPress={() =&gt; {
              Animated.timing(animationValue, {
                toValue: routeIndex,
                duration: 500,
                useNativeDriver: true
              }).start(() =&gt; {
                   onTabPress({ route });
              });
}}به همین راحتی و هم اکنون می تونیم مشاهده کنیم که بلهههه بلاخره یکم جذاب تر شده طراحیمون .و هم اکنون قسمت اولمون به پایان رسید :) ایشالله توی قسمت دوم مشکلات رو رفع می کنیم و کلی قشنگترش می کنیم .آدرس گیت هاب پروژه : https://github.com/AZIMAT/AnimatedTabBar</description>
                <category>عظیم عاطفی</category>
                <author>عظیم عاطفی</author>
                <pubDate>Sat, 27 Apr 2019 00:34:19 +0430</pubDate>
            </item>
                    <item>
                <title>روش بهینه سازی Flatlist در React Native</title>
                <link>https://virgool.io/iran-react-community/%D8%B1%D9%88%D8%B4-%D8%A8%D9%87%DB%8C%D9%86%D9%87-%D8%B3%D8%A7%D8%B2%DB%8C-flatlist-%D8%AF%D8%B1-react-native-uvo4i8trzvgg</link>
                <description>فلت لیست ها در React Native عملا یک نقش اساسی رو بازی می کنند و معمولا پیاده سازی های infinite scrolling باید با استفاده از این کامپوننت صورت بگیره چون بر خلاف ScrollView که تمامی آیتم های رنده شده رو چه داخل ViewPort باشند چه نباشند رو داخل رم نگه میداره FlatList که از خانواده Virtualizedlist ها هست زمانی که از آیتم رندر شده از ViewPort خارج بشه عملا از داخل رم پاک می شه.خب تا اینجایی که می بینیم FlatList خیلی خفنه اما! اینجا یه اما خیلی ترسناک هست و اونم اینه که Flatlist شما بهینه نوشته نشه عملا خیلی کندی و لگ کاربر شما حس می کنه یا توی اسکرول های سریع معمولا صفحه سفید رو میبینه که خیلی چیز قشنگی نیست :)خب حالا ما میخوایم با هم یکم Flatlist رو بهینه تر بنویسیم .خب اولین گام اینه که برای فرزنده های ساخته شده از لایف سایکل shouldcomponentupdate یا به جای ساختن فرزندان با استفاده از React.Component از React.PureComponent  استفاده کنیم مطمئنم اگه اولین مرحله رو رعایت کنیم قطعا خیلی از مشکلات حل میشن . class Test extends React.PureComponent {
    ...
}و هم اکنون میریم سراغ مرحله بعدی می تونیم داخل Flatlist مون از  removeClippedSubviews که در اصل میاد هنگامی که آیتم مورد نظر از ViewPort حذف میشه به صورت کامل پاکش می کنه و دفعه بعد برای نمایشش دوباره از اول رندرش می کنه خب اینکه خیلی خفنه می تونیم همیشه استفاده کنیم اینجاست که به یک عدد نه! بر میخوریم متاسفانه طبقه گفته خود فیسبوک این یکم باگ داره هنوز که نیاز داره فیکس بشه ولی خب پیشنهاد من اینکه برای اندروید استفاده کنید .به صورت زیرremoveClippedSubviews={Platform.OS == &#039;ios&#039; ? false : true}سومین مرحله ی ما در اصل استفاده از کامپوننت های ساده تر و عکس های کش شده و بهینه شده برای موبایل هست برای اینکه عکس های سریع تر لود بشن میتونیم از پکیج زیر استفاده کنیم که خیلی خفنه و سرعت لود عکس های کش رو خیلی افزایش میده .https://github.com/DylanVann/react-native-fast-imageحالا میایم سراغ مرحله ی آخر اگر هنوز هم مشکل داری تو Flatlist خودت که من بعید میدونم آخرین ترفند ما میتونه استفاده از getItemLayout باشه که عملا از البته زمانی به دردتون میخوره که اندازه تمامی کامپوننت های توی Flatlist مون هم اندازه باشن . داخل فلت لیست به صورت پیش فرض و پویا برای هر آیتم اندازه محاسبه میشه که خود این مورد باعث کند شدنش میشه با استفاده از getItemLayout ما خودمون محاسبه رو به عهده می گیریم.  getItemLayout = (data, index) =&gt; ({
     length: height, //height of our View
     offset: height* index,  //position of item in Flatlist
     index // index of item
   })
 راستی یادمون نره که از  keyExtractor هم استفاده کنیم چون اگه نکنیم اینکارو همه کامپوننت ها هر بار از ViewPort خارج میشن و میخوان برگردن به ViewPort دوباره رندر میشن به جای اینکه از cache بیان.امیدوارم Flatlist هاتون همیشه بی باگ و سریع باشه.</description>
                <category>عظیم عاطفی</category>
                <author>عظیم عاطفی</author>
                <pubDate>Thu, 25 Apr 2019 00:57:27 +0430</pubDate>
            </item>
            </channel>
</rss>