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

السؤال

نشر

لدي الكود البسيط التالي:

class ClassComponent extends React.Component{
  
  // دالة عادية يتم تنفيذها عند الضغط على العنصر p
  clickHandler(e){
    alert('Hello, World!');
  }
  
  render(){
    return <p onClick={clickHandler}>Content</p>
  }
}

ما لاحظته هو أنه يمكن إستخدام أكثر من طريقة في الجزء onClick={someEventHandler} كالتالي على سبيل المثال:

return <p onClick={this.clickHandler.bind(this)}>Content</p>

return <p onClick={(e) => { this.clickHandler(e) }>Content</p>

return <p onClick={this.clickHandler}>Content</p>

ما الفرق بين كل طريقة من الطرق السابقة؟ هل يجب أن ألتزم بطريقة واحدة منهم أم توجد حالات لإستعمال كل واحدة منهم؟ 

Recommended Posts

  • 0
نشر

الطريقة اﻷصح هي التالية:

class ClassComponent extends React.Component{
  constructor(){
    this.clickHandler = this.clickHandler.bind(this);
  }
  // دالة عادية يتم تنفيذها عند الضغط على العنصر p
  clickHandler(e){
    alert('Hello, World!');
  }
  
  render(){
    return <p onClick={this.clickHandler}>Content</p>
  }
}

لاحظ أننا نقوم بعمل binding في الباني وليس داخل render، بالنسبة للطرق الثلاثة فاﻷولى ستعمل بشكل صحيح ﻷنها تجنبك خطأ setState on undefined ولكن عمل binding عند كل render سيؤذي اﻷداء لذلك نقوم بها في الباني وليس في render.

بالنسبة للطريقتين اﻷخريتين فهما صحيحتان شرط أن تقوم بعمل bind داخل الباني ، من دون bind سيظهر لك خطأ setState on undefined.

مع وجود bind في الباني الطريقتان الثانية والثالثة كلاهما صحيحتان وشخصياً أفضل الطريقة الثالثة ﻷنها أقصر وﻷن الطريقة الثانية تنشئ تابع جديد عند كل render أيضاً مما قد يؤذي اﻷداء في بعض الحالات.

  • 0
نشر

كل الطرق التي ذكرتها سابقا تؤدي نفس الغرض لكن الاختلاف يكمن في كيفية العمل ففي الطريقة الاولي

export default class App extends Component {
 
  handleClick() {}

  render() {
    return (
      <div>
        <h1>title</h1>
        <Button onClick={this.handleClick.bind(this)}></Button>
      </div>
    );
  }
}

نستدعي ال bind داخل ال render وهذا يؤدي الغرض لكن هذا في كل مرة يشتغل فيها المكون سينشأ handler جديد مما سيؤدي الى عمل rerender لل button في الحالة السابقة وهذه نقطة عليك لا لك فيما يتعلق بكفاءة وسرعة عمل التطبيق الخاص بك.

الطريقة الثانية وهي الحل للمشكل المذكور سابقا هي القيام بالbinding في ال constructor 

export default class App extends Component {
  constructor() {
    super();
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {}

  render() {
    return (
      <div>
        <h1>title</h1>
        <button onClick={this.handleClick}>button</button>
      </div>
    );
  }
}

أما الطريقة الأنظف في رأيي هي استخدام ال arrow function في ال binding 

export default class App extends Component {
  constructor() {
    super();
    this.state = {
      name: 'salah',
    };
  }
  handleClick = () => {
    console.log(this.state.name);
  };

  render() {
    return (
      <div>
        <h1>title</h1>
        <button onClick={this.handleClick}>button</button>
      </div>
    );
  }
}

 

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

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

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

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

  • إعلانات

  • تابعنا على



×
×
  • أضف...