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

كود axios لا يقوم بتعديل قيمة متغير في مكون React؟

Adam Ebrahim

السؤال

لدي مكون React وبه متغير بسيط وأريد أن أقوم بتحديث قيمة هذا المتغير بناء على الـ response من طلب من خلال axios، لذلك قمت بعمل الكود التالي:

var friends = {}
axios.get('http://localhost:8080/api/people')
.then(function (response) {
  friends = response.data[0]

  // هنا يتم طباعة القائمة بشكل سليم
  console.log(friends)
})
.catch(function (error) {
  console.log(error)
})

// لكن ما يحدث هنا هو
// طباعة {}
console.log(friends)

لماذا لا يتم تحديث قيمة المتغير friends؟ ألا يمكن أن أستعمل هذا المتغير خارج التابع then؟

رابط هذا التعليق
شارك على الشبكات الإجتماعية

Recommended Posts

  • 0

ﻷن السطر الأخير يقوم بطباعة المتغير friends قبل حدوث الـxhr أصلا أي قبل أن تطرأ عليه أي تغيرات , على عكس ما داخل التابع then الذي هو مرتبط بما بعد حدوث الطلب . 

و لحل المشكلة يمكنك فقط إنشاء ميثود تقوم بإستعمال المتغير بمنطق معين من ضمن المكون يتم استدعاءها داخل التابع then , و هذا هو الأصح عمله على هذا النحو : 

var friends = {}
axios.get('http://localhost:8080/api/people')
.then(function (response) {
  friends = response.data[0]

  // استدعاء الدالة بعد عمل تغيرات على المتغير
  useFriends();
})
.catch(function (error) {
  console.log(error)
})


function useFriends(){
  console.log(friends);
}

 

تم التعديل في بواسطة Adnane Kadri
رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
  • يرجع ذلك إلي طريقة تنفيذ جافا سكربيت للكود عن طريق Javascript Runtime
  • في ال Javascript Runtime هناك أربع مكونات أساسيه هي Callstack, Web Api, Callback Queue, Event Loop
  • عند تنفيذ ملف جافا سكربيت يتم وضع الكود في ال Callstack إذا كان ال CallStack يمكنه تنفيذ هذا الكود وإذا لم يكون يتم إرساله الي Web API وبعد ما تنفذه ال Web  Api يتم وضعه في Callback Queue ثم يقوم ال Event Loop بفحص إذا ماكان ال Callstack فارغ ويمكنه استقبال كود جديد لتنفيذه وينتقل الكود لل Callstack ليتم تنفيذه
  • علي سبيل المثال
console.log("1");
setTimeout(() => {
	console.log("2");
}, 1000);
console.log("3");
// الناتج
// 1
// 3
// 2
  • عند تنفيذ هذا الاسكربيت يتم وضع console.log("1") و console.log("3") داخل ال Callstack ويتم تنفذهم وطباعة 1 و 3 ثم setTimeout يتم إرسالها إلي Web API لتقوم بتنفذها ثم يتم إرسالها إلي Callback Queue ثم يقوم Event loop بفحص ما إذا كان ال Callstack يمكنه استقبال الكود وتنفيذه ثم يتم ارسال الكود وتنفيذه وطباعة القيمه 2

 

  • الخطاء في الكود هو أنه سيتم وضع ال friends = {} ثم تنفذ جملة ال console.log(friends) ليطبع {} ثم يتم ارسال axios.get() function إلي ال Web API لتقوم بتنفذيها
رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0

في لغة JavaScript لديك مايعرف بالتنفيذ المتزامن synchronous و التنفيذ غير المتزامن asynchronous

الحالة الإفتراضية لتنفيذ الكود في JavaScript هو تنفيذ متزامن بحيث يتم تنفيذ الكود من الأعلى الى الأسفل من اليسار الى اليمين إلا في بعض الحالات مثل عند استخدام ميزة async الجديدة أو عمل طلب بإستخدام Fetch أو axios فهنا يتم تنفيذ هذا الكود بشكل غير متزامن

في الكود الخاص بك تم تنفيذ الكود المتزامن بالكامل ويتم تنفيذ الكود الغير المتزامن في حالتك استخدام axios بشكل منفصل

ومن ثم بعد الإنتهاء من الكود المتزامن يتم الرجوع الى الكود الغير المتزامن والتأكد إذا انتهى من التنفيذ

انظر الى ترتيب التنفيذ في الكود الخاص بك

var friends = {} // 1

axios.get('http://localhost:8080/api/people') 
.then(function (response) {
  friends = response.data[0] //3

  console.log(friends)
})
.catch(function (error) {
  console.log(error)
})

console.log(friends) // 2

بإختصار يجب تنفيذ الكود المتزامن بالكامل ومن ثم الكود الغير المتزامن

يمكنك إستخدام كود الأخ عدنان ليتم إستدعاء الدالة بعد إنتهاء تنفيذ الدالة الغير متزامنة والحصول على إستجابة

أو يمكنك إستخدام async await كما هو مبين في هذا الكود

var friends = {}

async function asyncFunc() { 
  try {
    friends = await axios.get("http://localhost:8080/api/people")
                        .then((response) => response.data[0])
    console.log(friends)
    
    } catch (err) {
        console.error(err);
    }
}

asyncFunc()

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...