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

من موسوعة حسوب
أنشأ الصفحة ب'<noinclude>{{DISPLAYTITLE:خاصيات التصيير}}</noinclude>'
 
لا ملخص تعديل
سطر 1: سطر 1:
<noinclude>{{DISPLAYTITLE:خاصيات التصيير}}</noinclude>
<noinclude>{{DISPLAYTITLE:خاصيات التصيير}}</noinclude>
يُشير مصطلح خاصيّة التصيير (render prop) إلى تقنية بسيطة لمشاركة الشيفرة بين مكوّنات React باستخدام خاصية والتي قيمتها هي عبارة عن دالة.
يأخذ المكوّن الذي يمتلك خاصيّة تصيير دالة تُعيد عنصر React ويستدعيها بدلًا من تنفيذ منطق التصيير الخاص به:<syntaxhighlight lang="javascript">
<DataProvider render={data => (
  <h1>أهلًا {data.target}</h1>
)}/>
</syntaxhighlight>تتضمّن المكتبات التي تستخدم خاصيّات التصيير React Router و Downshift.
سنناقش في هذه الصفحة فائدة خاصيّات التصيير وكيفية كتابة خاصيّات التصيير الخاصّة بك.
== استخدام خاصيّات التصيير للاهتمامات المشتركة ==
تُعد المكوّنات الوحدة الأساسية من الشيفرة القابلة لإعادة الاستخدام في React، ولكن ليس من الواضح كيفيّة مشاركة الحالة أو السلوك من مكوّن إلى مكوّن آخر يحتاج نفس الحالة.
على سبيل المثال يتتبع المكوّن التالي موقع الفأرة في تطبيق الويب:<syntaxhighlight lang="javascript">
class MouseTracker extends React.Component {
  constructor(props) {
    super(props);
    this.handleMouseMove = this.handleMouseMove.bind(this);
    this.state = { x: 0, y: 0 };
  }
  handleMouseMove(event) {
    this.setState({
      x: event.clientX,
      y: event.clientY
    });
  }
  render() {
    return (
      <div style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>
        <h1>حرك الفأرة</h1>
        <p>موقع الفأرة الحالي هو ({this.state.x}, {this.state.y})</p>
      </div>
    );
  }
}
</syntaxhighlight>بينما يتحرك المؤشر على الشاشة، يعرض المكوّن إحداثياته <code>(x, y)</code> ضمن العنصر ‎<code><nowiki><p></nowiki></code>‎.
السؤال الآن هو كيفيّة إعادة استخدام هذا السلوك في مكوّن آخر؟ أي بمعنى آخر إن احتاج مكوّن آخر إلى معرفة مكان المؤشر، فهل نستطيع تغليف هذا السلوك لمشاركته بسهولة مع ذلك المكوّن؟
لمّا كانت المكوّنات الوحدة الأساسية في React لإعادة استخدام الشيفرة، فلنجرّب إعادة ترتيب الشيفرة قليلًا لتستخدم المكوّن <code>‎<Mouse>‎</code> والذي يُغلِّف السلوك الذي نريد إعادة استخدامه في مكان ما:<syntaxhighlight lang="javascript">
// يغلف المكون <Mouse> السلوك الذي نحتاجه
class Mouse extends React.Component {
  constructor(props) {
    super(props);
    this.handleMouseMove = this.handleMouseMove.bind(this);
    this.state = { x: 0, y: 0 };
  }
  handleMouseMove(event) {
    this.setState({
      x: event.clientX,
      y: event.clientY
    });
  }
  render() {
    return (
      <div style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>
        {/* ... ولكن كيف نصير شيء آخر غير العنصر <p>? */}
        <p>موقع الفأرة الحالي هو: ({this.state.x}, {this.state.y})</p>
      </div>
    );
  }
}
class MouseTracker extends React.Component {
  render() {
    return (
      <div>
        <h1>حرك الفأرة</h1>
        <Mouse />
      </div>
    );
  }
}
</syntaxhighlight>يُغلِّف المكوّن ‎<code><Mouse></code>‎ الآن السلوك المرتبط بالاستماع إلى أحداث تحريك الفأرة <code>mousemove</code> وتخزين إحداثيات <code>(x, y)</code> لموقع المؤشر، ولكنّه ليس قابلًا لإعادة الاستخدام حتى الآن.
فلنفترض أننا نمتلك المكوّن ‎<code><Cat></code>‎ والذي يُصيِّر صورة لقطة تُطارِد الفأرة ضمن الشاشة. بإمكاننا استخدام الخاصيّة

مراجعة 12:35، 24 أغسطس 2018

يُشير مصطلح خاصيّة التصيير (render prop) إلى تقنية بسيطة لمشاركة الشيفرة بين مكوّنات React باستخدام خاصية والتي قيمتها هي عبارة عن دالة.

يأخذ المكوّن الذي يمتلك خاصيّة تصيير دالة تُعيد عنصر React ويستدعيها بدلًا من تنفيذ منطق التصيير الخاص به:

<DataProvider render={data => (
  <h1>أهلًا {data.target}</h1>
)}/>

تتضمّن المكتبات التي تستخدم خاصيّات التصيير React Router و Downshift.

سنناقش في هذه الصفحة فائدة خاصيّات التصيير وكيفية كتابة خاصيّات التصيير الخاصّة بك.

استخدام خاصيّات التصيير للاهتمامات المشتركة

تُعد المكوّنات الوحدة الأساسية من الشيفرة القابلة لإعادة الاستخدام في React، ولكن ليس من الواضح كيفيّة مشاركة الحالة أو السلوك من مكوّن إلى مكوّن آخر يحتاج نفس الحالة.

على سبيل المثال يتتبع المكوّن التالي موقع الفأرة في تطبيق الويب:

class MouseTracker extends React.Component {
  constructor(props) {
    super(props);
    this.handleMouseMove = this.handleMouseMove.bind(this);
    this.state = { x: 0, y: 0 };
  }

  handleMouseMove(event) {
    this.setState({
      x: event.clientX,
      y: event.clientY
    });
  }

  render() {
    return (
      <div style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>
        <h1>حرك الفأرة</h1>
        <p>موقع الفأرة الحالي هو ({this.state.x}, {this.state.y})</p>
      </div>
    );
  }
}

بينما يتحرك المؤشر على الشاشة، يعرض المكوّن إحداثياته (x, y) ضمن العنصر ‎<p>‎.

السؤال الآن هو كيفيّة إعادة استخدام هذا السلوك في مكوّن آخر؟ أي بمعنى آخر إن احتاج مكوّن آخر إلى معرفة مكان المؤشر، فهل نستطيع تغليف هذا السلوك لمشاركته بسهولة مع ذلك المكوّن؟

لمّا كانت المكوّنات الوحدة الأساسية في React لإعادة استخدام الشيفرة، فلنجرّب إعادة ترتيب الشيفرة قليلًا لتستخدم المكوّن ‎<Mouse>‎ والذي يُغلِّف السلوك الذي نريد إعادة استخدامه في مكان ما:

// يغلف المكون <Mouse> السلوك الذي نحتاجه
class Mouse extends React.Component {
  constructor(props) {
    super(props);
    this.handleMouseMove = this.handleMouseMove.bind(this);
    this.state = { x: 0, y: 0 };
  }

  handleMouseMove(event) {
    this.setState({
      x: event.clientX,
      y: event.clientY
    });
  }

  render() {
    return (
      <div style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>

        {/* ... ولكن كيف نصير شيء آخر غير العنصر <p>? */}
        <p>موقع الفأرة الحالي هو: ({this.state.x}, {this.state.y})</p>
      </div>
    );
  }
}

class MouseTracker extends React.Component {
  render() {
    return (
      <div>
        <h1>حرك الفأرة</h1>
        <Mouse />
      </div>
    );
  }
}

يُغلِّف المكوّن ‎<Mouse>‎ الآن السلوك المرتبط بالاستماع إلى أحداث تحريك الفأرة mousemove وتخزين إحداثيات (x, y) لموقع المؤشر، ولكنّه ليس قابلًا لإعادة الاستخدام حتى الآن.

فلنفترض أننا نمتلك المكوّن ‎<Cat>‎ والذي يُصيِّر صورة لقطة تُطارِد الفأرة ضمن الشاشة. بإمكاننا استخدام الخاصيّة