Abdullah Muhammad
-
المساهمات
118 -
تاريخ الانضمام
-
تاريخ آخر زيارة
إجابات الأسئلة
-
إجابة 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))
-
إجابة 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> ) }
-
إجابة 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> </> )
-
إجابة 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 ويظهر لك الخطأ
-
إجابة 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" قم بإستخدام الأمر مرة أخرى وسوف يعمل معك بإذن الله
-
إجابة 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); }); }} /> ); }
-
إجابة 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'))
-
إجابة 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.