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

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

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

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

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

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

    1

آخر يوم ربح فيه إسلام عبدالعزيز هو مارس 6 2021

إسلام عبدالعزيز حاصل على أكثر محتوى إعجابًا!

2 متابعين

آخر الزوار

لوحة آخر الزوار معطلة ولن تظهر للأعضاء

إنجازات إسلام عبدالعزيز

عضو نشيط

عضو نشيط (3/3)

69

السمعة بالموقع

22

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

  1. يمكنك استعمال 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. تسمح لك الخاصية keyboardShouldPersistTaps على الـ ScrollView ان تتحكم في لوحة المفاتيح بعد الضغط (tap). تأخذ هذه الخاصية واحدة من ثلاثة قيم: never ستقوم بعمل dismiss للوحة المفاتيح عند الضغط خارج الحقل النصي. always ستقوم بضبط لوحة المفاتيح بحيث لا تقوم بالاختفاء، ولكن سيتم تنبيه المكونات بالنقر. handled لن يتم تجاهل لوحة المفاتيح تلقائيًا عندما يتم التحكم في النقر من المكونات المدرجة. لذلك، يمكنك استخدام always او handled لتعمل كما تريد.
  3. هذه مشكلة 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).
  4. يمكن عمل Authentication بطريقة سهلة عن طريق SecureStore من مكتبة Expo، وتوفير التواصل بين المكونات عن طريق useReducer. import * as React from 'react'; import * as SecureStore from 'expo-secure-store'; export default function App({ navigation }) { const [state, dispatch] = React.useReducer( (prevState, action) => { switch (action.type) { // حالة تسجيل الدخول case 'SIGN_IN': return { ...prevState, isSignout: false, userToken: action.token, }; // حالة تسجيل الخروج case 'SIGN_OUT': return { ...prevState, isSignout: true, userToken: null, }; } }, { isLoading: true, isSignout: false, userToken: null, } ); React.useEffect(() => { // نقوم بقراءة الـ token والتحرك حسب قيمتها const bootstrapAsync = async () => { let userToken; try { userToken = await SecureStore.getItemAsync('userToken'); } catch (e) { } // هنا سنقوم بالتحويل لشاشة التسجيل او التطبيق وبعدها سنغلق التحميل dispatch({ type: 'RESTORE_TOKEN', token: userToken }); }; bootstrapAsync(); }, []); const authContext = React.useMemo( () => ({ signIn: async data => { // عمل تسجيل الدخول dispatch({ type: 'SIGN_IN', token: 'dummy-auth-token' }); }, signOut: () => dispatch({ type: 'SIGN_OUT' }), signUp: async data => { dispatch({ type: 'SIGN_IN', token: 'dummy-auth-token' }); }, }), [] ); // ستجد هنا يتم رسم المسار على حسب قيمة الـ token return ( <AuthContext.Provider value={authContext}> <Stack.Navigator> {state.userToken == null ? ( <Stack.Screen name="SignIn" component={SignInScreen} /> ) : ( <Stack.Screen name="Home" component={HomeScreen} /> )} </Stack.Navigator> </AuthContext.Provider> ); }
  5. مكتبة React Native Debugger ممتازة حيث انها تستخدم الـ WebWorker في Chrome عن طريق XMLHttpRequest او fetch بهذا الشكل: global.XMLHttpRequest = global.originalXMLHttpRequest ? global.originalXMLHttpRequest : global.XMLHttpRequest; global.FormData = global.originalFormData ? global.originalFormData : global.FormData; fetch; if (window.__FETCH_SUPPORT__) { window.__FETCH_SUPPORT__.blob = false; } else { global.Blob = global.originalBlob ? global.originalBlob : global.Blob; global.FileReader = global.originalFileReader ? global.originalFileReader : global.FileReader; } سنقوم بعمل right click ونختار Enable Network Inspector وسيظهر في المتصفح بشكل سهل.
  6. يوجد المتاح onScroll على مكون الـ ScrollView حيث يأخذ دالة callback وتحتوي هذه الدالة على معلومات الحدث الحالي لمكان الـ scroll. يمكن استخدامها لحساب الوصول لنهاية الصفحة، وبعدها تتم عملية تحميل الصور الجديدة. <ScrollView onScroll={handleScroll} /> وستجدي معلومات الـ X والـ Y بداخل الدالة handleScroll هكذا: const handleScroll = event => { const { x, y } = event.nativeEvent.contentOffset; };
  7. عند بناء التطبيقات، يعمل المطور على عمل Internationalization (i18n) وهي عملية تصميم التطبيق بحيث يكون قادر على الترجمة الى العديد من اللغات. المرحلة الثانية، هي مرحلة الـ Localization (l10n)، وهي مرحلة استخدام هذا التطبيق الذي قمنا بتصميمه لكي يكون قادراً على الترجمة، وترجمته الى اي لغة نريدها. يوجد العديد من المكتبات الجاهزة لعمل Localization بكل سهولة. لن تحتاج الى كتابة مكتبتك الخاصة. على سبيل المثال، اذا كنت تعمل على تطبيق React، فلديك مكتبة react-native-localize. طريقة عمل الـ Localization من الناحية البرمجية هي كالآتي: يتم تعريف اللغة الحالية للتطبيق في متغير يستخدمه التطبيق في مرحلة الـ bootstrapping. توجد مصفوفة بها اللغات التي يدعمها التطبيق، مع دالة لتغيير اللغة. يتم تعريف اي لغة جديدة في شكل كائن. عند كتابة اي نص في التطبيق، لا تتم كتابته باللغة العربية او الانجليزية، بل نستخدم دالة الـ localize او غالباً ما يكون اسمها "__" ونكتب داخلها مفتاح مميز لهذا النص في التطبيق. مثلاً، لو اردنا كتابة "مرحباً" في التطبيق، سنكتبها في شكل: __("HELLO"). لاحظ ان المفتاح "HELLO" هو الذي سيستخدمه التطبيق للترجمة. فلو كانت اللغة هي العربية، سيبحث التطبيق بداخل ملف اللغة العربية على المفتاح HELLO وسيجد انه يساوي "مرحباً"، وستتم طباعته، وهكذا.
  8. يمكنك إستخدام extraData حيث انها تقوم باخبار الـ FlatList ان عليها القيام بـ re-render. على سبيل المثال، يمكن أن تكون قيمة الـ extraData عبارة عن boolean: <FlatList extraData={this.state.update} وعندما نريد عمل update او re-render، سنقوم بعمل toggle لهذه القيمة ليحدث trigger لتحديث القائمة: this.setState({ update: !this.state.update }); السبب وراء عدم حدوث re-render هو ان الـ FlatList هي PureComponent في الاصل، حيث انه لن يحدث اي re-render عند تغيير الـ state والـ props بنفس القيمة.
  9. عليك بكتابة Native Module مخصص بداخل مجلد الـ android، على سبيل المثال، OpenSettingsModule.java بداخل android/app/src/main/java/com/<projectname>/opensettings. لا تنسى عمل register لهذا الـ module بداخل OpenSettingsPackage.java. سنقوم بكتابة الكود التالي بداخل OpenSettingsModule.java: package com.<projectname>.opensettings; import android.app.Activity; import android.content.Intent; import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.ReactContextBaseJavaModule; public class OpenSettingsModule extends ReactContextBaseJavaModule { @Override public String getName() { /** * .سيكون هذا اسم الوحدة التي سننشئها * * import { NativeModules } from 'react-native'; * * NativeModules.OpenSettings.openNetworkSettings( ... ); */ return "OpenSettings"; } @ReactMethod public void openNetworkSettings(Callback cb) { Activity currentActivity = getCurrentActivity(); if (currentActivity == null) { cb.invoke(false); return; } try { currentActivity.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS)); cb.invoke(true); } catch (Exception e) { cb.invoke(e.getMessage()); } } public OpenSettingsModule(ReactApplicationContext reactContext) { super(reactContext); } } الآن علينا تسجيل هذه الوحدة بداخل OpenSettingsPackage.java لنستطيع استخدامها: package com.<projectname>.opensettings; import com.facebook.react.ReactPackage; import com.facebook.react.bridge.JavaScriptModule; import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.uimanager.ViewManager; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class OpenSettingsPackage implements ReactPackage { @Override public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { List<NativeModule> modules = new ArrayList<>(); modules.add(new OpenSettingsModule(reactContext)); return modules; } @Override public List<Class<? extends JavaScriptModule>> createJSModules() { return Collections.emptyList(); } @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); } } قبل الاستعمال، علينا توفير الحزمة بداخل MainApplication.java هكذا: import com.<projectname>.opensettings.*; @Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(), new OpenSettingsPackage() /* .هذه هي الوحدة التي قمنا بكتابتها */ ); } والآن، قم باستعماله بداخل React Native هكذا: import { NativeModules } from 'react-native'; function App() { const openSettings() { NativeModules.OpenSettings.openNetworkSettings(data => {}); } return ( <View> <Text onPress={openSettings}>Open Settings</Text> </View> ); }
  10. يجب عليك ضبط متغير البيئة $JAVA_HOME لكي يشير الى تثبيت JDK عندك. اذا كنت تستعمل MacOS او Linux، قم بعمل: export JAVA_HOME="/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home" وبالنسية لـ Windows، قم باضافة JAVA_HOME الى متغيرات المستخدم لديك الى: "C://Program Files/Java/jdk_1.x_" اذا كنت لا تعلم مسار Java على جهازك (Windows)، قم بعمل: c:\> for %i in (java.exe) do @echo. %~$PATH:i
  11. لنتمكن من حفظ حالة التحرك في التطبيق، يمكننا استخدام onStateChange و initialState الموجودين لدى الحاوية (NavigationContainer). onStateChange تُعلمنا هذه الخاصية بأية تغييرات في الحالة، لذا يمكننا حفظ الحالة بداخلها. initialState تسمح لنا هذه الخاصية بتمرير حالة أولية، لذا يمكننا تمرير الحالة المستعادة بداخلها. ضع في اعتبارك أن الحالة تتم استعادتها بشكل غير متزامن (Asynchronous)، فعلينا اولاً ان نكتب مكون التحميل وحالته بهذا الشكل: import Loading from '../Loading'; if (!isReady) { return <Loading />; } سنقوم ايضاً بكتابة الثابت PERSISTENCE_KEY الذي سيستخدم لحفظ حالة التحرك عن طريق AsyncStorage. فمثلاً، عن تغير الحالة، سنكتب الدالة بداخل onStateChange هكذا: <NavigationContainer onStateChange={(state) => AsyncStorage.setItem(PERSISTENCE_KEY, JSON.stringify(state)) } ></NavigationContainer> والآن الجزء الاهم هو الدورة التي سنكتبها بداخل useEffect والتي ستكون بالشكل التالي: const [isReady, setIsReady] = React.useState(false); React.useEffect(() => { const restoreState = async () => { try { const initialUrl = await Linking.getInitialURL(); if (Platform.OS !== 'web' && initialUrl == null) { const savedStateString = await AsyncStorage.getItem(PERSISTENCE_KEY); const state = savedStateString ? JSON.parse(savedStateString) : undefined; if (state !== undefined) { setInitialState(state); } } } finally { setIsReady(true); } }; if (!isReady) { restoreState(); } }, [isReady]); يوجد ايضاً طريقة آخرى عن طريق استخدام مكون الـ Modal من React Native، حيث يمكننا إظهار Splash بداخله عندما تتغير حالة التطبيق: function App() { const [isModalVisible, setIsModalVisible] = React.useState(false); const handleStateChange = nextState => { if (state.current.match(/inactive|background/) && nextState === 'active') { setIsModalVisible(false); } else { setIsModalVisible(true); } }; return ( <React.Fragment> <AuthContext.Provider> <NavigationContainer> {/* ضع باقي التحويلات هنا */} <Modal animationType="slide" visible={isModalVisible} transparent={true}> <Splash /> </Modal> </NavigationContainer> </AuthContext.Provider> </React.Fragment> ); }
  12. لغة JSON هي طريقة للتواصل بين لغات البرمجة المختلفة. عن طريقها يمكنك كتابة كود في PHP ومن ثم تحويل المعلومات لـ Ruby وبعدها لـ JavaScript بكل سهولة. للعمل بـ JSON، تحتاج اولاً الى ترجمتها الى اللغة التي تعمل بها. على سبيل المثال، اذا كان عندك كائن في JSON، فعليك اولاً تحويله الى Hash ليعمل بداخل Ruby. لذا، لا يمكنك قراءة محتوى ملف JSON والعمل به فوراً. عليك اولاً ترجمته باستخدام مكتبة JSON بهذا الشكل: require 'json' # قراءة محتوى الملف plain = File.read('./db.json') # قم بالترجمة json = JSON.load(plain) # الآن يمكنك القراءة بسهولة puts json['name'] # يمكنك ايضاً تحويل الى JSON مرة أخرى هكذا JSON.generate({:hello => "world"});
  13. يستخدم React Router مكتبة تدعى path-to-regexp لفهم المسار المعطى. لذلك، تستطيع استخدام Regular Expressions بداخل المسار: <Route path="/(home|post|page)/" component={Page} /> أيضاً، تقبل الخاصية path نوعان من المعطيات: string او مصفوفة من strings. لذلك، يمكنك استخدام مصفوفة بهذا الشكل: <Route path={["/home", "/page", "/post"]} component={Page} />
  14. يمكننا تحقيق هذا عن طريق استخدام useRef مع createRef. const data = { posts: [ { title: 'كورس جافاسكريبت' }, { title: 'كورس علوم الكمبيوتر' } ] }; /** * سنقوم بكتابة مكون يطبع عناوين المقالات وبه مدخل نصي * .وزر لتغيير لون العناوين */ const App = () => { // .نستخدمها بالطريقة العادية للحصول على قيمة اللون const colorRef = React.useRef(null); // .هنا سنقوم بحفظ المراجع للمقالات // .ستلاحظ هنا ان قيمة المرجع هي مصفوفة من المراجع const references = React.useRef( data.posts.map(() => React.createRef()) ); // .دالة بسيطة للحصول على اللون ونداء العناصر لكل مرجع const changeColor = color => { // .لاحظ كيف يتم الوصول لمرجع كل مقالة references.current.forEach(ref => { ref.current.style.color = color; }); }; return ( <div> { data && data.posts.map((post, id) => ( <div ref={references.current[id]}> <h1>{post.title}</h1> </div> )) } <input ref={colorRef} type="text" placeholder="#AEF266" /> <button onClick={() => { changeColor(colorRef.current.value); }}>تغيير اللون</button> </div> ); }; ReactDOM.render( <App />, document.getElementById('root') );
  15. دعنا نلقي نظرة على الفرق بين: 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 );
×
×
  • أضف...