الفرق بين المراجعتين لصفحة: «React/state and lifecycle»

من موسوعة حسوب
لا ملخص تعديل
لا ملخص تعديل
سطر 81: سطر 81:
== إضافة الحالة المحلية للصنف ==
== إضافة الحالة المحلية للصنف ==
سننقل التاريخ <code>date</code> من الخاصيّات <code>props</code> إلى الحالة في ثلاث خطوات:
سننقل التاريخ <code>date</code> من الخاصيّات <code>props</code> إلى الحالة في ثلاث خطوات:
# تبديل <code>this.props.date</code> بـ <code>this.state.date</code> في التّابع <code>render()‎</code>:
 
-'''أولًا:''' تبديل <code>this.props.date</code> بـ <code>this.state.date</code> في التّابع <code>render()‎</code>:<syntaxhighlight lang="javascript">
class Clock extends React.Component {
class Clock extends React.Component {
 
  render() {
 render() {
    return (
 
      <div>
   return (
        <h1>أهلًا بالعالم!</h1>
 
        <h2>الساعة الآن {this.state.date.toLocaleTimeString()}.</h2>
     <nowiki><div></nowiki>
      </div>
 
    );
       <nowiki><h1>أهلًا بالعالم!</h1></nowiki>
  }
 
       <nowiki><h2>الساعة الآن {this.state.date.toLocaleTimeString()}.</h2></nowiki>
 
     <nowiki></div></nowiki>
 
   );
 
 }
 
}
}
# إضافة [[JavaScript/class|دالة بانية للصنف (constructor)]] والتي تُعيِّن القيمة المبدئية this.state:
</syntaxhighlight>-'''ثانيًا:''' إضافة [[JavaScript/class|دالة بانية للصنف (constructor)]] والتي تُعيِّن القيمة المبدئية <code>this.state</code>:<syntaxhighlight lang="javascript">
class Clock extends React.Component {
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }


 constructor(props) {
  render() {
 
    return (
   super(props);
      <div>
 
        <h1>أهلًا بالعالم!</h1>
   this.state = {date: new Date()};
        <h2>الساعة الآن {this.state.date.toLocaleTimeString()}.</h2>
 
      </div>
 }
    );
 
  }
 render() {
 
   return (
 
     <nowiki><div></nowiki>
 
       <nowiki><h1>أهلًا بالعالم!</h1></nowiki>
 
       <nowiki><h2>الساعة الآن {this.state.date.toLocaleTimeString()}.</h2></nowiki>
 
     <nowiki></div></nowiki>
 
   );
 
 }
 
}
}


لاحظ كيف مرّرنا الخاصيّات props إلى الدالة البانية:
</syntaxhighlight>لاحظ كيف مرّرنا الخاصيّات <code>props</code> إلى الدالة البانية:<syntaxhighlight lang="javascript">
 
constructor(props) {
constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }


   super(props);
</syntaxhighlight>ينبغي لمُكوِّنات الأصناف أن تستدعي دومًا الدالة البانية مع الخاصيّات <code>props</code>.
 
   this.state = {date: new Date()};
 
 }


ينبغي لمُكوِّنات الأصناف أن تستدعي دومًا الدالة البانية مع الخاصيّات props.
-'''ثالثًا:''' إزالة الخاصيّة <code>date</code> من العنصر ‎<code><Clock />‎</code>:<syntaxhighlight lang="javascript">
# إزالة الخاصيّة date من العنصر ‎<Clock />‎:
ReactDOM.render(
ReactDOM.render(
 
  <Clock />,
 <Clock />,
  document.getElementById('root')
 
 document.getElementById('root')
 
);
);


سنعيد لاحقًا إضافة شيفرة عداد الوقت إلى المُكوِّن نفسه.
</syntaxhighlight>سنعيد لاحقًا إضافة شيفرة عداد الوقت إلى المُكوِّن نفسه.
 
تبدو النتيجة كما يلي:


تبدو النتيجة كما يلي:<syntaxhighlight lang="javascript">
class Clock extends React.Component {
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }


 constructor(props) {
  render() {
 
    return (
   super(props);
      <div>
 
        <h1>أهلًا بالعالم!</h1>
   this.state = {date: new Date()};
        <h2>الساعة الآن {this.state.date.toLocaleTimeString()}.</h2>
 
      </div>
 }
    );
 
  }
 render() {
 
   return (
 
     <nowiki><div></nowiki>
 
       <nowiki><h1>أهلًا بالعالم!</h1></nowiki>
 
       <nowiki><h2>الساعة الآن {this.state.date.toLocaleTimeString()}.</h2></nowiki>
 
     <nowiki></div></nowiki>
 
   );
 
 }
 
}
}


ReactDOM.render(
ReactDOM.render(
 
  <Clock />,
 <Clock />,
  document.getElementById('root')
 
 document.getElementById('root')
 
);
);


جرِّب المثال على موقع CodePen.
</syntaxhighlight>[http://codepen.io/gaearon/pen/KgQpJd?editors=0010 جرِّب المثال على موقع CodePen].


سنجعل الآن المُكوِّن Clock يُعيِّن عدّاد الوقت الخاص به ويُحدِّث نفسه في كل ثانية.
سنجعل الآن المُكوِّن <code>Clock</code> يُعيِّن عدّاد الوقت الخاص به ويُحدِّث نفسه في كل ثانية.

مراجعة 16:44، 11 يوليو 2018

سنتحدّث في هذا القسم حول مفهوم حالة ودورة حياة المُكوِّنات في React، بإمكانك أن تجد من هنا مرجعًا مُفصّلًا حول واجهة برمجة التطبيق (API) للمُكوِّنات.

فلنتذكر مثال الساعة من قسم تصيير العناصر في React، تعلّمنا في ذلك القسم فقط طريقة واحدة لتحديث واجهة المستخدم عن طريق استدعاء التابع ReactDOM.render()‎ لتغيير الناتج:

function tick() {
  const element = (
    <div>
      <h1>أهلًا بالعالم!</h1>
      <h2>الساعة الآن {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(
    element,
    document.getElementById('root')
  );
}

setInterval(tick, 1000);

جرِّب المثال على موقع CodePen.

سنتعلّم في هذا القسم كيف نجعل مُكوِّن الساعة Clock قابلًا لإعادة الاستخدام حقًّا مع تغليفه ضمن نفسه، حيث يُعيِّن عدّاد الوقت الخاص به ويُحدِّث نفسه في كل ثانية.

بإمكاننا البدء عن طريق تغليف شكل السّاعة:

function Clock(props) {
  return (
    <div>
      <h1>أهلًا بالعالم!</h1>
      <h2>الساعة الآن {props.date.toLocaleTimeString()}.</h2>
    </div>
  );
}

function tick() {
  ReactDOM.render(
    <Clock date={new Date()} />,
    document.getElementById('root')
  );
}

setInterval(tick, 1000);

جرِّب المثال على موقع CodePen.

ولكن على الرغم من ذلك يفتقد هذا المُكوِّن لمتطلب أساسي، وهو أنّ تعيين السّاعة لعدّاد الوقت وتحديثها لواجهة المستخدم في كل ثانية ينبغي أن يكون تفصيلًا داخليًّا خاصًّا بالمُكوِّن Clock.

نريد بشكل مثالي أن نكتب هذه الشيفرة مرة واحدة ونجعل المُكوِّن Clock يُحدِّث نفسه:

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

لتنفيذ هذا نحتاج لإضافة حالة (state) إلى المُكوِّن Clock.

تُشبِه الحالة الخاصيّات props، ولكنّها خاصّة (private) ويتحكَّم فيها المُكوِّن.

أشرنا سابقًا في قسم المُكوِّنات والخاصيّات إلى أنّ المُكوِّنات المُعرَّفة كأصناف تمتلك ميزات إضافيّة، الحالة المحليّة (Local State) واحدة من هذه الميّزات فهي تتوفر فقط للأصناف.

تحويل الدالة إلى صنف

بإمكانك تحويل مُكوِّنات الدوال مثل Clock إلى أصناف بخمس خطوات:

  1. إنشاء صنف بنفس الاسم والذي يمتد (extends) إلى React.Component.
  2. إضافة تابع فارغ وحيد لهذا الصنف اسمه render()‎.
  3. نقل جسم الدالة إلى التّابع render()‎.
  4. تبديل props إلى this.props في جسم التّابع render()‎.
  5. حذف باقي تصريح الدالة الفارغ.
class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>أهلًا بالعالم!</h1>
        <h2>الساعة الآن {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

جرِّب المثال على موقع CodePen.

أصبح المُكوِّن Clock الآن مُعرَّفًا كصنف بدلًا من دالة.

سيُستدعى التّابع render()‎ في كل مرّة يحصل فيها تحديث، ولكن طالما أنّنا نُصيِّر (Render) العنصر ‎<Clock />‎ إلى نفس عقدة DOM، فستُستخدَم نسخة واحدة فقط من الصنف Clock، يسمح لنا هذا باستخدام ميزات إضافية مثل الحالة المحليّة ودورة حياة المُكوِّنات.

إضافة الحالة المحلية للصنف

سننقل التاريخ date من الخاصيّات props إلى الحالة في ثلاث خطوات:

-أولًا: تبديل this.props.date بـ this.state.date في التّابع render()‎:

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>أهلًا بالعالم!</h1>
        <h2>الساعة الآن {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

-ثانيًا: إضافة دالة بانية للصنف (constructor) والتي تُعيِّن القيمة المبدئية this.state:

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h1>أهلًا بالعالم!</h1>
        <h2>الساعة الآن {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

لاحظ كيف مرّرنا الخاصيّات props إلى الدالة البانية:

constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

ينبغي لمُكوِّنات الأصناف أن تستدعي دومًا الدالة البانية مع الخاصيّات props. -ثالثًا: إزالة الخاصيّة date من العنصر ‎<Clock />‎:

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

سنعيد لاحقًا إضافة شيفرة عداد الوقت إلى المُكوِّن نفسه. تبدو النتيجة كما يلي:

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h1>أهلًا بالعالم!</h1>
        <h2>الساعة الآن {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

جرِّب المثال على موقع CodePen.

سنجعل الآن المُكوِّن Clock يُعيِّن عدّاد الوقت الخاص به ويُحدِّث نفسه في كل ثانية.