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

السؤال

نشر (معدل)

أحاول كتابة دالة تقوم بعمل إجراء معين بعد عدة ثواني عند الضغط على زر محدد 

وهناك زر آخر الغرض منه إيقاف هذا الإجراء إذا تم الضغط عليه قبل انتهاء الوقت المحدد في setTimeout

ولكن الإجراء يتم سواء ضغطت على زر الإيقاف أم لم أضغط

ولا أعرف ما لخطأ في الكود

هذا هو الكود

const confirmAction = () => { // هذه الدالة تبدأ العمل عندما يتم الضغط على زر محدد
    setShowActionMessage(true);
    const timeout = setTimeout(() => {
      if (!stopAction) {
        setAction(true);
        doTheAction(); // هذه الدالة المستهدفة من هذه العملية
      }
    }, 5000);
    if (stopAction) { // عند الضغط على زر الإيقاف true هذه الحالة تصبح
      clearTimeout(timeout);
    }
  };

كما ترون أنا أستعمل الريآكت وأستخدم ال useState و if condition للوصول للنتيجة المرغوبة 
ولكن للأسف الدالة المستهدفة لا يتم إيقافها ولا أعرف لماذا وهي تتفعل بعد انتهاء الـ 5 ثواني

تم التعديل في بواسطة فينيكس العربي
خطأ إملائي

Recommended Posts

  • 0
نشر

أولا المشكلة تحدث لأنك تحاول إيقاف ال setTimeout بعد إنشاءه . وهذا خطأ .

فالذى يحدث فعليا أن تنشأ دالة setTimeout وترجع id مثلا ب 1 وإذا قيمة timeout تصبح 1 .

وحين الضغط على الزر الإلغاء سيدخل للدالة confirmAction ويقوم بإنشاء setTimeout جديد ب id جديد ولنقل مثلا 2  وإذا ستصبح قيمة timeout ب 2 و سيقوم بإلغاء ال setTimeout التي لها id يساوي 2 و لكن ال id الذي يساوي 1 لم يتم إيقافه لذلك سوف ينفذ .

والحل هو التالي :

const confirmAction = () => { // هذه الدالة تبدأ العمل عندما يتم الضغط على زر محدد
    setShowActionMessage(true);
    if (stopAction) { // عند الضغط على زر الإيقاف true هذه الحالة تصبح
        clearTimeout(timeout);
      }else {
        const timeout = setTimeout(() => {
      if (!stopAction) {
        setAction(true);
        doTheAction(); // هذه الدالة المستهدفة من هذه العملية
      }
    }, 5000);
      }
  };

ولكن سيحدث خطأ وهو بسبب عدم تعريف ال timeout لذلك يجب وضعها في useState حتي يكون ال id معك في جميع الأحوال وإيقافه من أي مكان .

والأفضل جعلهما دالتين حيث الدالة confirmAction مسؤولة فقط عن إنشاء setTimeout ودالة أخري مثلا cancelAction وهي مسؤولة عن الإلغاء

  • 0
نشر (معدل)
بتاريخ 38 دقائق مضت قال محمد عاطف17:

أولا المشكلة تحدث لأنك تحاول إيقاف ال setTimeout بعد إنشاءه . وهذا خطأ .

فالذى يحدث فعليا أن تنشأ دالة setTimeout وترجع id مثلا ب 1 وإذا قيمة timeout تصبح 1 .

وحين الضغط على الزر الإلغاء سيدخل للدالة confirmAction ويقوم بإنشاء setTimeout جديد ب id جديد ولنقل مثلا 2  وإذا ستصبح قيمة timeout ب 2 و سيقوم بإلغاء ال setTimeout التي لها id يساوي 2 و لكن ال id الذي يساوي 1 لم يتم إيقافه لذلك سوف ينفذ .

والحل هو التالي :

const confirmAction = () => { // هذه الدالة تبدأ العمل عندما يتم الضغط على زر محدد
    setShowActionMessage(true);
    if (stopAction) { // عند الضغط على زر الإيقاف true هذه الحالة تصبح
        clearTimeout(timeout);
      }else {
        const timeout = setTimeout(() => {
      if (!stopAction) {
        setAction(true);
        doTheAction(); // هذه الدالة المستهدفة من هذه العملية
      }
    }, 5000);
      }
  };

ولكن سيحدث وهو بسبب عدم تعريف ال timeout لذلك يجب وضعها في useState حتي يكون ال id معك في جميع الأحوال وإيقافه من أي مكان .

والأفضل جعلهما دالتين حيث الدالة confirmAction مسؤولة فقط عن إنشاء setTimeout ودالة أخري مثلا cancelAction وهي مسؤولة عن الإلغاء

سأحاول ولكن ما لقيمة الإفتراضية للuseState

تم التعديل في بواسطة فينيكس العربي
  • 0
نشر
بتاريخ 1 دقيقة مضت قال محمد عاطف17:

هذا ما أخبرتك به أنه سيحدث خطأ لانه لن يجد timeout لذلك يجب إستخدام useState  ل useState حتي يتم حفظه في المكون لديك .

و يفضل إرسال كود المكون كاملا .

ما القيمة الإفتراضية للuseState

  • 0
نشر
بتاريخ 6 دقائق مضت قال محمد عاطف17:

يمكنك بوضعها null أو false والتأكد في الشطر الخاص ب stopAction أن لا تكون القية null أو false علي حسب القيمة الإفتراضية التي وضعهتها

 

مازلت عالق أخي

اكتب لي الطريقة كاملة إن أمكن 

 

دقيقة سأرسل الكود


  const [showDeleteMessage, setShowDeleteMessage] = useState(false);
  const [stopDeleting, setStopDeleting] = useState(false);
  const [deleting, setDeleting] = useState(false);

const handleStopDeleting = () => {
    setStopDeleting(true);
    setShowDeleteMessage(false);
    console.log("Stop deleting!");
  };

  const deleteMyPost = async () => {
    try {
      // عملية حذف البوست
    } catch (error: any) {
      // الخطأ
    }
  };
  const confirmDeleting = () => {
    setShowDeleteMessage(true);
    const timeout = setTimeout(() => {
      if (!stopDeleting) {
        setDeleting(true);
        deleteMyPost();
      }
    }, 5000);
    if (stopDeleting) {
      clearTimeout(timeout);
    }
  };

return {
  <button onClick={confirmDeleting}> "delete post" </button>
  <button onClick={handleStopDeleting}> "cancel" </button>
}

هذا هو الكود

أخي ليس بالضرورة أن تكون setTimeout و clearTimeout في نفس الدالة

المهم أن تؤدي المطلوب

  • 0
نشر
const [showDeleteMessage, setShowDeleteMessage] = useState(false);
const [stopDeleting, setStopDeleting] = useState(false);
const [deleting, setDeleting] = useState(false);
const [timeout, setTimeout] = useState(false);

const handleStopDeleting = () => {
    setStopDeleting(true);
    setShowDeleteMessage(false);
    clearTimeout(timeout);
    console.log("Stop deleting!");

};

const deleteMyPost = async () => {
    try {
        // عملية حذف البوست
    } catch (error: any) {
        // الخطأ
    }
};
const confirmDeleting = () => {
    setShowDeleteMessage(true);
    const timeout = setTimeout(() => {
        if (!stopDeleting) {
            setDeleting(true);
            deleteMyPost();
        }
    }, 5000);
    setTimeout(timeout);
};

return {
  <button onClick={confirmDeleting}> "delete post" </button>
  <button onClick={handleStopDeleting}> "cancel" </button>
}

الخطأ الأساسي أنك عند الضغط على زر cancel لم تستدعي الدالة التي تقوم بإلغاء الحذف بل فقط كنت تقوم بتغير القيمة فكان يجب عليك الضغط على cancel ثم delete post للإيقاف .

ولكن الآن قد قمت بفصل الإثنين لك عند الضغط على cancel تقوم بإلغاء setTimeout

  • 0
نشر
بتاريخ 7 دقائق مضت قال محمد عاطف17:
const [showDeleteMessage, setShowDeleteMessage] = useState(false);
const [stopDeleting, setStopDeleting] = useState(false);
const [deleting, setDeleting] = useState(false);
const [timeout, setTimeout] = useState(false);

const handleStopDeleting = () => {
    setStopDeleting(true);
    setShowDeleteMessage(false);
    clearTimeout(timeout);
    console.log("Stop deleting!");

};

const deleteMyPost = async () => {
    try {
        // عملية حذف البوست
    } catch (error: any) {
        // الخطأ
    }
};
const confirmDeleting = () => {
    setShowDeleteMessage(true);
    const timeout = setTimeout(() => {
        if (!stopDeleting) {
            setDeleting(true);
            deleteMyPost();
        }
    }, 5000);
    setTimeout(timeout);
};

return {
  <button onClick={confirmDeleting}> "delete post" </button>
  <button onClick={handleStopDeleting}> "cancel" </button>
}

الخطأ الأساسي أنك عند الضغط على زر cancel لم تستدعي الدالة التي تقوم بإلغاء الحذف بل فقط كنت تقوم بتغير القيمة فكان يجب عليك الضغط على cancel ثم delete post للإيقاف .

ولكن الآن قد قمت بفصل الإثنين لك عند الضغط على cancel تقوم بإلغاء setTimeout

الان أصبح يقوم بحذف البوست مباشرة عند الضغط على delete post ولا يعطيني فرصة للإلغاء

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

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

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

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   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.

  • إعلانات

  • تابعنا على



×
×
  • أضف...