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

السؤال

نشر (معدل)

لدي الكود التالي:

import React, { useState } from "react";
import ReactDOM from "react-dom";

function Settings() {
  const [username, setUsername] = useState();

  return (
    <input
      value={username}
      onChange={(e) => {
        setUsername(e.target.value);
        console.log(username);
      }}
    />
  );
}

الكود كما هو ظاهر بسيط للغاية ولكن المشكلة هي أن console.log لا تقوم بعرض القيمة الحالية بل القيمة القديمة!! بالرغم من أن حالة المكون يتم تحديثها بنجاح. ما السبب في ذلك؟ وكيف يمكنني تخطي هذه المشكلة؟

تم التعديل في بواسطة Adam Ebrahim

Recommended Posts

  • 1
نشر

السبب في ذلك أن 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);
          });
        }}
      />
    );
  }

 

  • 0
نشر

السبب في ذلك أن تابع setUsername لا يقوم بتحديث قيمة username آنياً بل يضعها ضمن batch of updates ليقوم ReactJS بتحديث عدة قيم لعدة hooks دفعة واحدة من أجل اﻷداء لذلك بعد انتهاء تابع setUsername من التنفيذ لن تكون قيمة username قد تحدثت بعد لذلك طبعاً سوف يطبع القيمة القديمة.

  • 0
نشر

كما شرح المدرب أحمد عند طباعة ال username لم يتم تحديث قيمة ال state عمل المطلوب بالأعلى عن طريق وسائل أخرى مثل

  • بدلاً من استخدام قيمة ال state يمكنك استخدام 
    console.log(e.target.value);

     

  • أو يمكنك استخدام ال hook useEffect كالتالي
useEffect(() => console.log(username), [username]);

 

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

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

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

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

  • إعلانات

  • تابعنا على



×
×
  • أضف...