اذهب إلى المحتوى

إسلام عبدالعزيز

الأعضاء
  • المساهمات

    93
  • تاريخ الانضمام

  • تاريخ آخر زيارة

  • عدد الأيام التي تصدر بها

    1

إجابات الأسئلة

  1. إجابة إسلام عبدالعزيز سؤال في كيف اتمكن من استعمال jQuery مع React Native كانت الإجابة المقبولة   
    يمكنك استعمال jQuery ولكن ليس بهذا الشكل. لانه لا يمكنك استعمال jQuery مع React Native. السبب هو ان React Native لا يعتمد على الـ DOM او الـ HTML، وله التكوين الـ native الخاص به. تطبيقات React Native تعتمد على JavaScript في المنطق (Logic) والـ representation للـ view فقط، وليس رسم الـ view نفسه، لان ذلك هو مهمة الـ OS (Android or iOS).
    يمكنك استخدام jQuery فقط اذا كنت تستعمل WebView لانه عبارة عن تحميل browser view بداخل التطبيق.
    import * as React from 'react'; import { Text, View, StyleSheet } from 'react-native'; import { WebView } from 'react-native-webview'; const html = ` <html> <body> <h1 id="title">Hello!</h1> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script> jQuery('#title').css({ color: 'red' }); </script> </body> </html> `; function App() { return ( <WebView originWhitelist={['*']} source={{ html }} /> ); } export default App;  
  2. إجابة إسلام عبدالعزيز سؤال في مشكلة عدم تحديث بيانات fetch في React Native كانت الإجابة المقبولة   
    هذه مشكلة caching للطلب. يمكنك استعمال الـ headers التالية بداخل fetch لتتكمن من جلب آخر التحديثات.
    fetch(url, { headers: { 'Cache-Control': 'no-cache, no-store, must-revalidate' } }); لاحظ اننا قمنا باستعمال القيم no-cache, no-store, must-revalidate. معاني كل واحدة فيهم هي:
    no-cache: يجب علم check قبل عمل caching للنتيجة. no-store: لا تقم بعمل caching مطلقاً. must-revalidate: يمكن استخدام النسخة المحلية اذا كانت اصغر من العمر (max-age).
  3. إجابة إسلام عبدالعزيز سؤال في ما المقصود ب localization بالنسبة للتطبيق ؟؟ كانت الإجابة المقبولة   
    عند بناء التطبيقات، يعمل المطور على عمل Internationalization (i18n) وهي عملية تصميم التطبيق بحيث يكون قادر على الترجمة الى العديد من اللغات.
    المرحلة الثانية، هي مرحلة الـ Localization (l10n)، وهي مرحلة استخدام هذا التطبيق الذي قمنا بتصميمه لكي يكون قادراً على الترجمة، وترجمته الى اي لغة نريدها.
    يوجد العديد من المكتبات الجاهزة لعمل Localization بكل سهولة. لن تحتاج الى كتابة مكتبتك الخاصة. على سبيل المثال، اذا كنت تعمل على تطبيق React، فلديك مكتبة react-native-localize.
    طريقة عمل الـ Localization من الناحية البرمجية هي كالآتي:
    يتم تعريف اللغة الحالية للتطبيق في متغير يستخدمه التطبيق في مرحلة الـ bootstrapping. توجد مصفوفة بها اللغات التي يدعمها التطبيق، مع دالة لتغيير اللغة. يتم تعريف اي لغة جديدة في شكل كائن. عند كتابة اي نص في التطبيق، لا تتم كتابته باللغة العربية او الانجليزية، بل نستخدم دالة الـ localize او غالباً ما يكون اسمها "__" ونكتب داخلها مفتاح مميز لهذا النص في التطبيق. مثلاً، لو اردنا كتابة "مرحباً" في التطبيق، سنكتبها في شكل: __("HELLO"). لاحظ ان المفتاح "HELLO" هو الذي سيستخدمه التطبيق للترجمة. فلو كانت اللغة هي العربية، سيبحث التطبيق بداخل ملف اللغة العربية على المفتاح HELLO وسيجد انه يساوي "مرحباً"، وستتم طباعته، وهكذا.
  4. إجابة إسلام عبدالعزيز سؤال في ما الفرق بين Calling a function وpassing a reference ؟؟ كانت الإجابة المقبولة   
    دعنا نلقي نظرة على الفرق بين:
    Pass by Value Pass by Reference أولاً: ما هي Pass by Value؟
    يتم استدعاء الدوال عن طريق تمرير قيمة المتغير مباشرة. لا يؤثر تغيير المعطى داخل الدالة على المتغير الذي يتم تمريره من خارج الدالة. أيضًا، ضع في اعتبارك أن جافاسكريبت دائمًا تمرر بالقيمة.
    // .تقوم الدالة بتغيير قيمة المعطيات // .ولكن، بما انها تمرر بالقيمة، لن تتغير القيم خارج الدالة function usingPassByValue( a, b ) { a = 1024; b = 512; console.log( `a: ${a} and b: ${b}` ); } // Global Scope تعريف قيم في الـ let a = 1, b = 2; // a: 1024 and b: 512 usingPassByValue( a, b ); // ما زالت تساوي 1 كما هي console.log( a ); // ما زالت تساوي 2 كما هي console.log( b ); ثانياً: ما هي Pass by Reference؟
    التمرير بالمرجع سيكون له تأثير على القيمة المعطاة. في جافاسكريبت، يتم تمرير الكائنات والمصفوفات عن طريق المرجع. لذلك إذا مررنا كائنًا أو مصفوفة كمعطى إلى الدالة، فهناك احتمال أن تتغير قيمة الكائن أو المصفوفة.
    function usingPassByReference( user ) { user.isOnline = true; } let adam = { isOnline: false }; usingPassByReference( adam ); // isOnline تم تغيير قيمة console.log( adam.isOnline );  
  5. إجابة إسلام عبدالعزيز سؤال في إخفاء لوحة المفاتيح عند الضغط على أي مكان في الشاشة React Native كانت الإجابة المقبولة   
    يمكنك استخدام مكون عالي المستوى لتحقيق ذلك.
    import React from 'react'; import { TouchableWithoutFeedback, Keyboard, View } from 'react-native'; const DismissKeyboard = Comp => { return ({ children, ...props }) => ( // TouchableWithoutFeedback // .يعمل عن طريق جعل أحد المكونات ملموسًا، ولكن دون أن يستجيب بتعليقات مرئية <TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}> <Comp {...props}> {children} </Comp> </TouchableWithoutFeedback> ); }; const DismissKeyboardView = DismissKeyboard(View) والآن يمكنك إستخدامها هكذا:
    const Test = () => { return ( <DismissKeyboardView> <TextInput /> </DismissKeyboardView> ); };  
  6. إجابة إسلام عبدالعزيز سؤال في تنظيف المسار المطلق React Native كانت الإجابة المقبولة   
    قم بتحميل بلجن module-resolver لـ Babel:
    yarn add --dev babel-plugin-module-resolver وبداخل ملف الـ configurations في tsconfig.json، قم بضبط المسارات هكذا:
    { "compilerOptions": { "paths": { "@app/*": ["app/*/index", "app/*"] } } } والآن، سنستخدم الـ plugin الذي قمنا بتحميله:
    module.exports = { presets: ['module:metro-react-native-babel-preset'], plugins: [ [ require.resolve('babel-plugin-module-resolver'), { cwd: 'babelrc', extensions: ['.ts', '.tsx', '.js', '.ios.js', '.android.js'], alias: { '@app': './app' } } ], 'jest-hoist' ] }; بعدها، قم بعمل restart للـ IDE، وستجد نفسك قادراً على استعمال المسارات بهذا الشكل:
    import constants from '@app/constants';  
  7. إجابة إسلام عبدالعزيز سؤال في مشكلة Module Resolution عند تشغيل تطبيق React Native كانت الإجابة المقبولة   
    قم أولاً بعمل:
    react-native start -- --reset-cache وبعدها:
    react-native run-android يظهر هذا الخطأ عند الترقية بين نسختين من RN.
  8. إجابة إسلام عبدالعزيز سؤال في عمل render ديناميكي عن طريق مسارات الصور React Native كانت الإجابة المقبولة   
    يجب عليك استدعاء الصور في React Native عن طريق:
    سطر الـ require باستخدام الخاصية uri بداخل source // الطريقة الأولى class AppComponent extends React.Component { constructor() { super(); this.state = { images: [ require('./src/photos/01.jpg'), require('./src/photos/02.jpg') ] }; } } /*** *** أو *** ***/ // الطريقة الثانية class DynamicImageComponent extends React.Component { render() { return ( <Image source={{ uri: this.props.source }} /> ); } };  
  9. إجابة إسلام عبدالعزيز سؤال في WebView لا يعمل في React Native كانت الإجابة المقبولة   
    يمكنك حل هذه المشكلة عن طريق عمل render للـ WebView بداخل Fragment بدلاً من View. يمكنك أيضاً إستعمال StyleSheet لتحديد خاصية العرض (width) وسوف يعمل الـ WebView بعدها.
    function App() { const [ready, setReady] = React.useState(false); React.useEffect(() => { setTimeout(() => { setReady(true); }, 4000); }); return ( <> { ready ? <WebView originWhitelist={['*']} source={{ html }} /> : <SplashScreen /> } </> ); }  
  10. إجابة إسلام عبدالعزيز سؤال في مشكلة تصميم Higher Order Component في React Native كانت الإجابة المقبولة   
    عند استخدام JSX، فعليك الانتابه ان المكون يجب ان يكون عبارة عن دالة. يريد React دائماً ان يحصل على المكونات في دالة او class، على حسب الاصدار الذي تستعمله. في الدالة withState، الراجع منها ليس دالة، بل انه كائن (object). كيف هذا؟ عند كتابة المكون في شكل JSX، يقوم Babel (المترجم) بعمل نداء لهذا المكون.
    على سبيل المثال، اذا قمت بكتابة الدالة الآتيه:
    function Button({ title }) {} // عندما نستخدم المكون كـ JSX // <Button title="Save" /> // هذا يساوي الآتي // Button({ title: "Save" }) لذلك، بداخل الدالة withState، يجب ان يكون الراجع منها دالة، وهذه الدالة يكون الراجع منها هو المكون نفسه. فسيكون الحل هكذا:
    const withState = state => Component => { return () => <Component {...state} />; }; او يمكن كتابة الدالة بدون الـ Arrow Functions هكذا:
    const withState = state => Component => { return function () { return <Component {...state} />; } };  
  11. إجابة إسلام عبدالعزيز سؤال في خطأ this.state is undefined في React؟ كانت الإجابة المقبولة   
    في لغة الجافاسكريبت، كل دالة لها context او سياق لتعمل فيه. لو قمنا بكتابة دالة عادية خارج React، وقمنا بعمل log للـ this، ستجد انها تشير الى النطاق/السياق العام (Window for Browsers & Global for Node). عندما نكتب مكون في React، نريد دائماً ان نشير للاحداث ان تعمل على المكون نفسه، وليس السياق العام. ولكن ما يحدث هو ما شرحته من قبل، حيث ان الـ methods بداخل المكون لا تأخذ سياقه.
    لهذا السبب، تقدم جافاسكريبت bind وهي دالة تستخدم لتغيير السياق العام لدالة معينة. انظر للمثال التالي:
    // السياق هنا هو window function logThis() { console.log(this); } logThis(); // => Window {} const car = { color: 'red', speed: 260 }; // الآن سنحول السياق الى كائن السيارة ونضعه في دالة جديدة const logThisCar = logThis.bind(car); logThisCar(); // => {color: "red", speed: 260} لذا، لربط اي دالة بمكون الـ React قم باستخدام bind بداخل الـ constructor هكذا:
    constructor(props) { super(props); this.state = {code: ''}; // هنا this.login = this.login.bind(this); }  
  12. إجابة إسلام عبدالعزيز سؤال في إضافة أقسام إلى الشريط الجانبي للمحرر كانت الإجابة المقبولة   
    يوفر ووردبريس واجهة برمجية من خلال JavaScript لتمكين إضافة اللوحات إلى الشريط الجانبي. يعد تسجيل مكون إضافي للشريط الجانبي سهلاً عن طريق استخدام الدالة registerPlugin المضمنة داخل ووردبريس كما يلي:
    import { PluginSidebar, PluginSidebarMoreMenuItem } from '@wordpress/edit-post'; import { registerPlugin } from '@wordpress/plugins'; import { more } from '@wordpress/icons'; const Component = () => ( <> <PluginSidebarMoreMenuItem target="sidebar-name" >My Sidebar</PluginSidebarMoreMenuItem> <PluginSidebar name="sidebar-name" title="My Sidebar" >Content of the sidebar</PluginSidebar> </> ); registerPlugin( 'plugin-name', { icon: more, render: Component, scope: 'my-page', } ); ستلاحظ أننا نستخدم صيغة JSX. هذا لأن حزم ووردبريس عبارة عن غلاف حول React.
    قبل التشغيل، نحتاج إلى تثبيت الحزم المطلوبة باستخدام:
    npm install @wordpress/plugins --save يمكنك الآن إنشاء الكود الخاص بك على غرار إنشاء تطبيق React باستخدام:
    npm run build سيكون الرمز المترجم جاهزًا. انقله إلى مجلد الأصول في مجلد WordPress الخاص بك. في الخطوة الأخيرة، نحتاج إلى تضمين هذا الرمز في صفحة المحرر. استخدم الإجراء "enqueue_block_editor_assets" هكذا:
    <?php add_action( 'enqueue_block_editor_assets', 'x_editor_assets' ); function x_editor_assets() { wp_enqueue_script( 'x-editor-script', plugins_url( '/assets/js/build.js', __FILE__ ) ); } الآن لديك لوحة الشريط الجانبي المخصصة الخاصة بك. يمكنك إضافة ما تريد داخل اللوحة. في حالتك، أضف حقل إدخال للون داخل مكون "PluginSidebar" بالشكل التالي:
    <PluginSidebar> <PanelBody> <TextControl label="First Color" /> <TextControl label="Second Color" /> </PanelBody> </PluginSidebar> الآن لديك القدرة على تحديد لونين للتدرج اللوني الخاص بك. باستخدام خدمات WordPress REST، يمكنك إرسال هذه القيم إلى قاعدة البيانات الخاصة بك كقيم Meta للصورة. وبعد ذلك يمكنك تحميل هذه الألوان على الواجهة الأمامية وتطبيق اللونين باستخدام CSS. يتضمن WordPress أيضًا على حزمة لطلبات AJAX للتواصل باستخدام REST:
    npm install @wordpress/data --save npm install @wordpress/compose --save import { withDispatch, withSelect } from '@wordpress/data'; const SidebarMeta = compose( // نستخدم "withSelect" لقراءة القيم من قاعدة البيانات withSelect(select => ({ // قيمة اللون هنا value: select('core/editor').getEditedPostAttribute('meta')['color_meta_key'] })), // نستخدم "withDispatch" لكتابة القيم إلى قاعدة البيانات withDispatch(dispatch => ({ write: color => { dispatch('core/editor').editPost({ meta: { 'color_meta_key': color } }); } })) );  
  13. إجابة إسلام عبدالعزيز سؤال في كيفية حل كل ما ورد في الـ Saga (React Native) كانت الإجابة المقبولة   
    تتكون حلقة الـ Redux Saga من الـ JavaScript Generators. كما تعلم، فعند إنشاء، على سبيل المثال، ساجا للـ Auth بالشكل التالي لعمل تسجيل خروج للمستخدم:
    function* requestLogout() { const isLogged = yield select(authSelectors.isLogged); if (isLogged) { yield call(authModels.logout); } yield put(authActions.logout()); } ستلاحظ أن كل شئ يتم تمريره ياستخدام الـ Effects مثل call و put مع الـ generators عن طريق yield.
    بكل بساطة، القيم العائدة من الـ yields هي نوع من التعليمات في شكل كائنات (object) ليستطيع Redux Saga تمريرها للـ saga التالية. لذا، عند عمل الـ root saga للتطبيق، يحب أولاً تحويل الدالة الى generator واستخدام التأثير all:
    function* rootSagas() { yield all([...authSagas, ...notificationSagas]); }  
  14. إجابة إسلام عبدالعزيز سؤال في لماذا نستخدم if class_exists في WordPress كانت الإجابة المقبولة   
    يعتمد ذلك على إصدار PHP الذي تستخدمه. اعتبارًا من PHP 5.3.0، هذا ليس ضروريًا. بدلاً من ذلك، من الأفضل استخدام الـ Namespaces.
    تدعم بيئات الاستضافة الحديثة PHP 5.3.0 على الأقل، إن لم تكن أعلى، ولهذا السبب، لا يتعين علينا استخدام class_exists إلا في بعض الحالات الخاصة جدًا، مثل إنشاء مكتبة Dependency Injection، وتعريف طريقة الـ dependency resolution، وهذه مواضيع معقدة لا يجب أن تشغل نفسك بها إلا عندما تتقن أساسيات اللغة أولاً.
    يمكنك التفكير في الـ Namespace مثل حزمة مكونة من قطع فريدة. لا يمكن أن تكون هناك قطعتان متماثلتان في نفس الحزمة. لذلك، في أي كود حديث، مثل Laravel، ستلاحظ أنهم يستخدمون Namespaces بدلاً من class_exists، لأن الـ Namespaces ستتأكد دائمًا من وجود أو عدم وجود الـ class قبل أن يتم دمجه أو تعريفه في النطاق.
    الطريقة القديمة:
    <?php if ( ! class_exists( 'MyClass' ) ) { class MyClass {} } الطريقة الحديثة:
    <?php namespace MyScope; class MyClass { }  
  15. إجابة إسلام عبدالعزيز سؤال في تمرير مصفوفة إلى الدالة كانت الإجابة المقبولة   
    لحل هذه المشكلة، علينا تقسيمها إلى أجزاء أصغر (سأقوم بإستخدام جافاسكريبت، ولكن خطوات الحل يمكن تنفيذها في أي لغة).
    أول مشكلة: كيف أجد الآحاد في رقم معين؟ في كل لغات البرمجة، يوجد مفهوم الـ modulus. الـ modulus هو العلامة % وتستخدم لإرجاع الباقي من رقم معين. مثلاً، إذا أردنا أن نحصل على الآحاد من الرقم 12345، يمكننا أن نفعل هذا:
    12345 % 10 // => 5 56789 % 10 // => 9 تم حل أول مشكلة، ويمكننا الآن الحصول على الآحاد بسهولة.
    الآن نريد أن نكتب دالة لتقوم بعمل حلقة حول المصفوفة المعطاه، وجمع الآحاد من الأرقام الموجودة بها. في هذه الحالة، يمكننا إستخدام reduce، وهي method جاهزة تعمل على المصفوفات في جافاسكريبت. تقوم هذه الدالة بأخذ مدخلين. المدخل الآخير هو القيمة التي سنبدأ بها الحلقة. فمثلاً، سنقوم بجمع أرقام الآن، لذا سنبدأ بـصفر. المدخل الأول، هو عبارة عن دالة، تأخذ مدخلين أيضاً. الأول هو المجموع الحالي الذي وصلنا إليه، والثاني هو العنصر الحالي.
    function getOnesDigit(n) { return n % 10; } function sumRightDigits(digits) { return digits.reduce((total, current) => total + getOnesDigit(current), 0); } sumRightDigits([10, 21, 3, 8, 9, 11, 44, 62, 100]); // => 28  
  16. إجابة إسلام عبدالعزيز سؤال في كيف أجعل index الخاص ب FlatList يتغير عندما أضغط على زر معين بدلا من السحب ؟ كانت الإجابة المقبولة   
    لقد قمت بتعديل الإجابة. يجب أن نستخدم الـ references بإستخدام current:
    flatListRef.current.scrollToIndex({ ... })  
  17. إجابة إسلام عبدالعزيز سؤال في عدم ظهور الصورة في react كانت الإجابة المقبولة   
    كما وضح المدرب صلاح، الطريقة الصحيحة هي إستخدام الـ import statements لجلب الصورة.
    لكن، دعني أضيف أيضاً أنه، على الرغم من أن هذه الطريقة هي الطريقة الصحيحة والمحبذة، إلا أنه هناك طريقة أخرى بدون إستعمال import في الملف.
    إذا ألقيت نظرة على الـ folders الموجودة بداخل المشروع الذي تعمل عليه، ستجد أنه هناك 2 folders وهما:
    المجلد src: وهذا الذي تضع في داخله كل أكواد React التي تكتبها. المجلد public: وهذا يحتوي على ملف أساسي وهو index.html. ذلك الملف هو الذي يقوم React بعمل hosting له على الـ localhost، ويقوم React أيضاً بعمل compile للكود الذي كتبته وضمه في ملف موحد وإدخاله في الـ index.html كـ script عادي. لهذا، فإنه يمكنك نقل الصور إلى مجلد الـ public وبالتالي يمكنك إستدعائها بكل بساطة.
    مثلاً، لو قمت بوضع صورة إسمها user.jpg بداخل الـ public folder، يمكنك إستدعائها من أي مكان بهذا الشكل:
     

  18. إجابة إسلام عبدالعزيز سؤال في العمل بدون إطار عمل في no framework php كانت الإجابة المقبولة   
    كما وضح المدرب سمير والمدرب وائل أنه يجب إستخدام إطار عمل للمشاريع الحقيقية، ولكن، دعني أعطيك بعض المواضيع التي يمكنك البحث عنها لتقوية خلفيتك في PHP.
    لا تثق أبدًا في المستخدمين للتطبيق: لو كان عندك حقل إدخال، أو query في URL، عليك عمل فلترة لهم قبل أن يمروا على تطبيقك. إذا لم تفعل هذا، فسيكون تطبيقك مُعرض لهجمات الـ XSS والـ SQL Injection. أستخدم HTTPS دائماً: هذا سيجعل إتصال المُستخدمين على موقعك آمن، وسيمنع الـ sniffing. أيضاً، المتصفحات الحديثة، مثل Google Chrome بدأت تضع لوحات تحذير لو كان موقعك يستعمل HTTP فقط. الملفات العامة: تأكد من ضبط الخادم الخاص بك بحيث لا يستضيف أي ملفات خاصة قد تحتوي على بيانات مهمة. قم بتضمين رمز CSRF مميز مع إجراءات التطبيق: إذا ألقيت نظرة على زر "أعجبني" الموجود على أي صفحة في أكاديمية حسوب، ستجد أنه في نهاية الـ URL يوجد CSRF Token مرفقة في النهاية. بدون هذه الـ token، يمكن لأي شخص أن يضع رابط الإعجاب في ملف HTML ويرسله إلى شخص لديه حساب على موقع الأكاديمية، وعند فتح هذا الملف، سيتم عمل إعجاب بشكل تلقائي بدون معرفة المُستخدم. طبعاً هذا مثال بسيط، ولكن يمكن أن يحدث على مستوى أعلى، مثل إضافة admin على الموقع. تشفير كلمات المرور: لا تقم بحفظ كلمات المرور كما هي في قاعدة البيانات. قم بالبحث عن طرق التشفير لتعرف أكثر. وأخيراً، بالنسبة إلى تنظيم الملفات، تأكد من أنك على دراية بـ Object Oriented Programming جيداً + نمط التصميم المشهور MVC. إن لم تكن تريد العمل بـ MVC، فعلى الأقل، تأكد أنك تفصل بين الملفات التي تعرض الـ UI، أو التي نُطلق عليها الـ views، وبين الملفات التي تتعامل مع قاعدة البيانات أو أي API خطير. آمل أن أكون قد أجبت على سؤالك.
  19. إجابة إسلام عبدالعزيز سؤال في روابط react-router لا تعمل عند تحديث الصفحة كانت الإجابة المقبولة   
    يمكنك إستخدام React Router النسخة الجديدة بهذه الطريقة، حيث أن الدالة run أصبحت غير صالحة في النسخة الجديدة، وغير محبذ ان تستخدمها.
    import React from 'react'; import ReactDOM from 'react-dom'; import { BrowserRouter, Route, Link, Switch } from 'react-router-dom'; function Home() { return <h1>Home</h1>; } function About() { return <h1>About Us</h1>; } ReactDOM.render( <BrowserRouter> <div> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/about">About</Link> </li> </ul> </div> <Switch> <Route path="/about"> <About /> </Route> <Route path="/"> <Home /> </Route> </Switch> </BrowserRouter>, document.getElementById('root') );  
  20. إجابة إسلام عبدالعزيز سؤال في لماذا dispatch يأخذ القيمة انتجر القديمة للمرة الاولى فقط وليست الجديدة المحدثة عندما أستخدم useState ؟ ويأخذ القيمة الجديدة المحدثة بواسطة setState فى المرة الثانية ؟؟ كانت الإجابة المقبولة   
    ممتاز! لقد قمت بكتابة تطبيق مشابه الآن، وقمت بإستعمال number و setNumber بداخل الـ store وكانت القيمة تعمل بشكل سليم. هل يمكنك مشاركة الكود كامل لأستطيع مساعدتك؟ أريد أن أشغل التطبيق لأستطيع إعطائك حل سليم 100%.
  21. إجابة إسلام عبدالعزيز سؤال في keys في react كانت الإجابة المقبولة   
    دعني أعطيك مثالاً حقيقياً لفهم الـ keys.
    لنفترض أن لديك قائمة من الألوان.
    <ul> <li>Green</li> <li>Blue</li> </ul> إذا أردت إضافة لون جديد إلى نهاية القائمة، فسيكون ذلك سهلاً على React.
    بكل بساطة، سينظر React للألوان، وسيجد أن العنصر الأول ما زال Green، والعنصر الثاني ما زال Blue، لذا سيكتفي React بدفع اللون الجديد في نهاية القائمة، وليكن اللون هذا Yellow.
    ولكن، لنفترض دفع لون جديد "Red" إلى بداية القائمة.
    <ul> <li>Red</li> <li>Green</li> <li>Blue</li> </ul> الآن لدينا مشكلة. لماذا؟
    سينظر React للألوان ويجد أن أول عنصر أصبح "Red" وليس "Green" كما كان متوقع.
    لن يقوم React بالنظر على القائمة كلها، وسوف يفترض أنه عليه تغيير كل العناصر في القائمة ليصل إلى شكل القائمة الجديد.
    المشكلة هنا أن React قام بعمليات ليست لها فائدة، ولو كانت هذه القائمة كبيرة، وتحتوي على عناصر كثيرة، سيكون التطبيق بطيئًا جدًا.
    الحل هو إستخدام الـ property key على أي عناصر داخل قائمة.
    في المثال الأول، سيكون:
    <ul> <li key="1">Green</li> <li key="2">Blue</li> </ul> وعند إضافة عنصر جديد إلى بداية القائمة، مع الوضع في الإعتبار أننا نريد السرعة، وعدم عمل أي تغييرات ليست مهمة:
    <ul> <li key="0">Red</li> <li key="1">Green</li> <li key="2">Blue</li> </ul> الآن، سينظر React للألوان وسيجد أنه هناك key على كل عنصر. لذا، سيبدأ بحساب التغييرات اللازمة عن طريق القيم المعطاه في الـ key.
    سيجد React أن العنصر Green ما زال يحصل القيمة 1 في الـ key، والعنصر Blue ما زال يحصل على 2 في الـ key وسيكتفي بدفع العنصر الجديد إلى بداية القائمة.
×
×
  • أضف...