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

Abdullah Muhammad

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

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

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

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

  1. إجابة Abdullah Muhammad سؤال في async thunk في redux toolkit كانت الإجابة المقبولة   
    يمكنك إستخدام createAsyncThunk 

    الخطوة الأولى قم بإنشاء "thunk" كالتالي 
    const fetchUserById = createAsyncThunk(   'users/fetchByIdStatus',   async (userId, thunkAPI) => {     const response = await userAPI.fetchById(userId)     return response.data   } ) الخطوة الثانيه
    قم بالتعامل مع هذا الأكشن داخل ال reducer 
    عن طريق إستخدام extraReducers كالتالي 
    const usersSlice = createSlice({   name: 'users',   initialState: { entities: [], loading: 'idle' },   reducers: {   },   extraReducers: {     [fetchUserById.fulfilled]: (state, action) => {       state.entities.push(action.payload)     },   }, })
    وأخيرا يمكنك أن تستدعي هذا ال "thunk" وعمل "dispatch"
    dispatch(fetchUserById(123))  
  2. إجابة Abdullah Muhammad سؤال في عمل موقع متعدد اللغات بإستخدام Gatsby كانت الإجابة المقبولة   
    يمكنك إستخدام   gatsby-plugin-intl لإنشاء موقع متعدد اللغات وذلك كالتالي 
    npm install gatsby-plugin-intl بعد ذلك في ملف gatsby-config.js نقوم بإضافة الإعدادات الخاصه بالإضافة كالتالي 
    module.exports = { plugins: [ { resolve: `gatsby-plugin-intl`, options: { // المسار الذي سيتواجد به ملفات الترجمه path: `${__dirname}/src/langs`, // اللغات التي تود إستخدامها languages: [`ar`, `en`], // اللغة الإفتراضية للموقع defaultLanguage: `ar`, }, }, ], } بعد ذلك في المسار الذي حددته تقوم بإنشاء ملف خاص بكل لغه يحتوي على ترجمة المصطلحات المطلوبه ولكن لابد من مراعاة بعض الأمور 
    لابد أن يكون إسم الملف كالتالي "[language].json" ف علي سبيل المثال "ar.json" "en.json" لابد من إستخدام نفس ال id الدال على الترجمه في كل ملف بحيث يكون شكل الملفات الناتجة كالتالي  // ar.json { "aboutUs": "عنا", "comments": "التعليقات", "home": "الصفحة الرئيسية" } // وفي ملف en.json { "aboutUs": "about us", "comments": "Comments", "home": "Home Page" } بعد ذلك يمكنك تطبيق الترجمه داخل كل مكون او صفحة كالتالي 
    import React from "react" import { useIntl } from "gatsby-plugin-intl" export default function Index() { const intl = useIntl() const locale = intl.locale !== "en" ? `/${intl.locale}` : "" return ( <div>{intl.formatMessage({ id: "home" })}</div> ) } حيث أنه بإستخدام "formatMessage" وتمرير ال id الذي نريد إيجاد الترجمة الخاصة به سوف يتم توليد المحتوى المطلوب على حسب اللغة المختاره

    يتبقى لنا أن نعرف كيف نقوم بالتبديل بين اللغات المتوفرة لدينا وذلك كالتالي
    import React from "react" import { Link } from "gatsby" export default function LanguageSelector({ label, className }) { return ( <div> <ul> <li> <Link to="/en">En</Link> </li> <li> <Link to="/">Ar</Link> </li> </ul> </div> ) }  
  3. إجابة Abdullah Muhammad سؤال في إضافة jQuery إلى موقع مبني بـ React - Gatsby كانت الإجابة المقبولة   
    يمكننا إستخدام jquery بطريقتين 
    الإولى من CDN وذلك كالتالي  في ملف gatsby-ssr.js 
    const React = require("react") export const onRenderBody = ({ setHeadComponents }, pluginOptions) => { setHeadComponents([ <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossOrigin="anonymous"> </script>, ]) } بعد ذلك في نحتاج أن نضيف jquery إلى ويب باك وذلك في ملف gatsby-node.js كالتالي
    exports.onCreateWebpackConfig = ({ actions, }) => { const { setWebpackConfig } = actions; setWebpackConfig({ externals: { jquery: 'jQuery', } }) } الثانيه ما إذا كان مشروعك يتضمن ملفات ال jquery يمكنك إستخدام helmet في هذه الحالة كالتالي
    // layout.js import { withPrefix } from "gatsby" const Component = ({ children }) => ( <> <Helmet> <script src={withPrefix('../../scripts/jquery.min.js')} type="text/javascript" /> </Helmet> </> )  
  4. إجابة Abdullah Muhammad سؤال في كيفية علاج الخطأ GET /questions 304 فى Node js كانت الإجابة المقبولة   
    تنفيذك للطريقة الأولى خاطئه فكان لابد أن يكون الكود النهائي بالشكل التالي في ملف index.js
    // index.js const questRouter = require("./router/questions"); app.use(express.json()); app.use(morgan("tiny")); app.get('/*', function(req, res, next){ res.setHeader('Last-Modified', (new Date()).toUTCString()); next(); }); app.use("/questions", questRouter); بالنسبة للفرونت إند فلديك خطأ بسيط هنا 
    <Text>{questions[index].name}</Text> حيث أنك تقوم بعرض الإسم الخاص بالسؤال صاحب index صفر 
    ولكن في أول مرة يعرض فيها المكون يكون 
    index = 0
    questions = []
    وبالتالي لايوجد شئ في الاندكس صفر ويكون الناتج undefined ويظهر لك الخطأ
  5. إجابة Abdullah Muhammad سؤال في اخطاء أوامر npm كانت الإجابة المقبولة   
    قم بتحميل النسخة الأخيره من node من هنا
    في حالة لم يعمل الأمر معك قم بإتباع الخطوات التاليه 
    قم بإنشاء مجلد بإسم "nodejs" في أحد المسارين التاليين "C:\Program Files (x86)"  أو "C:\Program Files" من قائمة start قم بالبحث عن "edit the system environment variables" وقم بفتحها   من قائمة Advanced قم بالضغط على Environment Variables في الجزء العلوي قم بالبحث عن "path" وقم بالضغط عليها سوف تنبثق لك نافذه (مرفق صورة للتوضيح) قم بالضغط على "New" ومن ثم قم بلص المسار الذي أنشأت فيه المجلد في الخطوه واحد سيكون بالشكل“C:\Program Files (x86)\nodejs” أو “C:\Program Files \nodejs “. بعد ذلك قم بالضغط على "OK"  قم بإستخدام الأمر مرة أخرى وسوف يعمل معك بإذن الله

  6. إجابة Abdullah Muhammad سؤال في جملة console.log لا تعرض حالة المكون الحالية في React؟ كانت الإجابة المقبولة   
    السبب في ذلك أن React كما أجبتك سابقا لاتقوم بتحديث ال state مباشرة في حالة كنا خارج عملية غير تزامنيه (Asynchronous) بل تقوم بعمل batching وتقوم بعملية التحديث لعدة قيم في ال state مرة واحده حتى لا يحدث render عدد كثير من المرات
    ولذا بما أنك تستخدم ال hooks يمكنك أن تستخدم ال useEffect  لتنفيذ المطلوب عن طريق التالي: 
    useEffect(() => { console.log(username); }, [username]); حيث سيتم تنفيذ الكود فقط في حالة تغيرت قيمة ال username في ال State

    وفي حالة أردت تنفيذ نفس الأمر في حالة كنت تستخدم class component يمكنك أن تنفذ الأمر كالتالي: 
    render() { return ( <input value={this.state.username} onChange={(e) => { this.setState({ username: e.target.value }, () => { console.log(this.state.username); }); }} /> ); }  
  7. إجابة Abdullah Muhammad سؤال في محتوى الصفحة لا يتغير في react-router؟ كانت الإجابة المقبولة   
    في البداية دعنا نفهم كيف يعمل ال router 
    على سبيل المثال إذا كان عنوان الموقع الخاص بنا 
    www.example.com
    فحين الولوج الى الموقع يقوم الروتر بأخذ مابعد .com  وهنا الإفتراضي هو "/"والبحث عنه بأسلوب إذا وجدت اي مسار داخل ال BrowserRouter يبدأ ب "/" فقم بعرض المكون الخاص بهذا المسار 
    ولذا ففي المثال المرفق حينما تقوم بتغير المسار إالى "www.example.com/profile"  يقوم الروتر بإقتطاع الجزء بعد .com وهو "profile/"  ويذهب ليبحث ويرى أي مسار يبدأ بأي شئ يطابق "profile/" في الترتيب حيث أن اول جزء هو "/" فيكون متطابقا مع أول مسار "/" فيقوم بعرض المكون الخاص به 
    ولذا فيمكننا حل هذا الأمر بعدة طرق منها التالى: 
    1- إستخدام Switch 
    import React from "react"; import ReactDOM from "react-dom"; import { Route, Switch } from "react-router"; import { BrowserRouter } from "react-router-dom"; import People from "./components/People"; import Profile from "./components/Profile"; ReactDOM.render( <BrowserRouter> <Switch> <Route path="/" component={People} /> <Route path="/profile" component={Profile} /> </Switch> </BrowserRouter>, document.getElementById("root") ); 2- إستخدام كlلة exact ك props وبالتي سيطابق المسار الموجود بالجزء المقتطع تماما 
    ReactDOM.render(( <BrowserRouter> <Route exact path="/" component={People} /> <Route exact path="/profile" component={Profile} /> </BrowserRouter> ), document.getElementById('root'))  
  8. إجابة Abdullah Muhammad سؤال في متى يتم إستخدام callback function في setState؟ كانت الإجابة المقبولة   
    اذا ما نظرنا الى الطريقة الاولى سنجد الاتي: 
    نحن نقوم بتخزين النتائج القادمه من ال API مباشرة الى friends وكل النتائج السابقه ستحذف 
    أما الطريقة الثانيه فنحن نضيف النتائج الجديده الى القديمه 
    ولكن مال الفرق الجوهري حقا بين الاسلوبين
    الاسلوب الثاني اذا مالاحظت فإنه يكون لديك وصول كامل الى ال state الحاليه   قبل ان تقوم بأي تعديل علىيها فيمكنك هنا ان تفحص مثلا اذا كان هناك اسم مكرر في قائمة الاصدقاء ف تحذفه أو تقوم بأي عمليات أخرى على الاستيت القديمه والقيمه الجديده ومن ثم تخزن القيم النهائيه في ال state وكل ذلك عكس الطريقة الاولى حيث لا يمكنك عمل ذلك.
    وهناك سبب أخر لوجود مثل هذا التكنيك رقم 2 وهو أن ريأكت تقوم بعمل مايسمى ب batching لل setState بمعنى اذا تم استدعاء setState أكثر من مره على التوالي كالاتي مثلا:
    state = { count: 0 } updateCount = () => { this.setState({ count: this.state.count + 1}); this.setState({ count: this.state.count + 1}); this.setState({ count: this.state.count + 1}); this.setState({ count: this.state.count + 1}); } سوف يتم تنفيذ الأخيرة فقط بمعنى ان ال count في النهايه سوف يزيد بمقدار واحد فقط وتصبح قيمة ال count تساوي واحد
    وللتغلب على هذا نستخدم الاسلوب الثاني حيث يكون لدينا الوصول على ال state قبل التعديل عليها ونضيف عليها واحد كالاتي: 
     
    updateCount = () => { this.setState(prevstate => ({ count: prevstate.count + 1})); this.setState(prevstate => ({ count: prevstate.count + 1})); this.setState(prevstate => ({ count: prevstate.count + 1})); this.setState(prevstate => ({ count: prevstate.count + 1})); } فتصبح قيمة ال count  في النهايه تساوي 4.
     
×
×
  • أضف...