ویژگی‌های (prop) رندر React

گردآوری و تالیف : عرفان کاکایی
تاریخ انتشار : 22 شهریور 1397
دسته بندی ها : جاوا اسکریپت

ویژگی‌های رندر، (Render prop) یک روش تقریبا جدید برای به اشتراک گذاری / استفاده مجدد کد در React است. React router و Downshift کتابخانه‌هایی هستند که از ویژگی‌های رندر استفاده می‌کنند.

یک ویژگی رندر چیست؟ اساسا یک ویژگی رندر، ویژگی‌ای به همراه یک تابع به عنوان مقدارش است. این ویژگی رندر، کامپوننت را از آنچه که باید رندر کند، مطلع می‌سازد. طبق اسناد خود React، یک کامپوننت به همراه یک ویژگی رندر، یک تابع را می‌گیرد که یک عنصر React را بر می‌گرداند و به جای پیاده‌سازی منطق رندر خود، آن را فراخوانی می‌کند.

حال که می‌دانیم ویژگی‌های رندر چیستند، بیایید آن‌ها را در حین عمل ببینیم.

با استفاده از ویژگی‌های رندر، از کد خود مجددا استفاده کنید

اساسا، کاری که ما می‌خواهیم انجام دهیم، به اشتراک گذاری state / رفتار یک کامپوننت موجود با دیگر کامپوننت‌ها که همان state را نیاز دارند است.

پس برای مثال، یک برنامه ساده داریم که حرکت موس را بر روی صفحه دنبال می‌کند:

import React from 'react'

import ReactDOM from 'react-dom'



const App = React.createClass({

  state = { x: 0, y: 0 }



  handleMouseMove = (event) => {

    this.setState({

      x: event.clientX,

      y: event.clientY

    })

  },



  render() {

    const { x, y } = this.state



    // همینطور که موس در صفحه حرکت می‌کند، کامپوننت موقعیت آن را نشان می‌دهد.

    return (

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

        <h1>The mouse position is ({x}, {y})</h1>

      </div>

    )

  }

})

ReactDOM.render(<App/>, document.getElementById('app'))

اگر می‌خواستید این رفتار را با دیگر کامپوننت‌ها به اشتراک بگذارید، چگونه از ویژگی رندر برای جمع‌بندی آن استفاده می‌کنید؟

import React from 'react'

import ReactDOM from 'react-dom'

import PropTypes from 'prop-types'



class Mouse extends React.Component {

  static propTypes = {

    render: PropTypes.func.isRequired

  }



  state = { x: 0, y: 0 }



  handleMouseMove = (event) => {

    this.setState({

      x: event.clientX,

      y: event.clientY

    })

  }



  render() {

    return (

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

        {this.props.render(this.state)}

      </div>

    )

  }

}



class App extends React.Component {

  render() {

    return (

      <div style={{ height: '100%' }}>

        <Mouse render={({ x, y }) => (

          <h1>The mouse position is ({x}, {y})</h1>

        )}/>

      </div>

    )

  }

}



ReactDOM.render(<App/>, document.getElementById('app'))

کاری که در اینجا انجام داده‌ایم، این است که یک کامپوننت‌ جدید به نام <Mouse> ساخته‌ایم، که یک ویژگی رندر را می‌گیرد. مقدار این ویژگی، یک تابع است. سپس این ویژگی در رندر <Mouse> استفاده شده است، تا تعیین کند که چه چیزی باید رندر شود.

نکته: state متعلق به <Mouse>، با استفاده از ویژگی رندر در معرض کامپوننت <App> قرار داده شده است. این مسئله کامپوننت App را قادر می‌سازد تا هر چیزی که می‌خواهد را با آن state رندر کند.

ویژگی رندر در <Mouse> آن را قادر می‌سازد تا به صورت دینامیک تعیین کند که چه چیزی باید رندر شود. از این رو، کاملا قابل حمل است و می‌توانیم از آن برای موارد زیادی استفاده کنیم.

import React from 'react'

import ReactDOM from 'react-dom'

import PropTypes from 'prop-types'

import cat from "./cat.png";



class Mouse extends React.Component {

  static propTypes = {

    render: PropTypes.func.isRequired

  }



  state = { x: 0, y: 0 }



  handleMouseMove = (event) => {

    this.setState({

      x: event.clientX,

      y: event.clientY

    })

  }



  render() {

    console.log("mouse", this.state)

    return (

      <div onMouseMove={this.handleMouseMove}>

        {this.props.render(this.state)}

      </div>

    )

  }

}



class Cat extends React.Component {

  render() {

    const {x, y} = this.props.mouse;



    return (

      <img src={cat} style={{ position: 'absolute', left: x, top: y, height: 50 }} />

    );

  }

}



class App extends React.Component {

  render() {

    return (

      <div>

        <div>

          <Mouse render={({ x, y }) => (

            <h1>The mouse position is ({x}, {y})</h1>

          )}/>

        </div>



        // موارد استفاده مختلف برای موقعیت موس

        <div>

          <Mouse render={({ x, y }) => (

            <Cat mouse={{ x, y }} />

          )}/>

        </div>

      </div>

    )

  }

}



export default App;

ما یک کامپوننت جدید به نام <Cat> اضافه کردیم که از رفتار موقعیت موس برای حرکت دادن یک گربه بر روی صفحه استفاده می‌کند.

به یاد داشته باشید که ما نمی‌خواهیم از ویژگی‌ای به نام render استفاده کنیم. تا زمانی که از یک ویژگی استفاده کنیم که مقدارش یک تابع است، که کامپوننت از آن برای این استفاده می‌کند که تعیین کند چه چیزی را باید رندر کند، ما در حال استفاده از الگوی render prop (ویژگی رندر) خواهیم بود. با توجه به این مسئله، می‌توانیم از ویژگی‌های فرزند (child prop) استفاده کنیم:

<Mouse children={({ x, y }) => (

  <p>The mouse position is {x}, {y}</p>

)}/>

این معمولا در قالب مفهوم «فرزندان به عنوان یک تابع» (Children as a function) شناخته می‌شود و دقیقا به مانند render prop است. React-motion از این مفهموم استفاده می‌کند.

نتیجه گیری

کار ما به اتمام رسیده است. ویژگی‌های رندر استفاده مجدد از کد را بسیار ساده می‌کنند. به یاد داشته باشید، هر زمان که کامپوننتی می‌سازیم، می‌خواهیم در حد ممکن قابلیت استفاده مجدد را داشته باشد.

منبع

مقالات پیشنهادی

چرا به Context API جدید React نیاز داریم ؟

چندین سال پیش، Context API به عنوان یک ویژگی آزمایشی با هشدار «این API در آینده می‌تواند بشکند» معرفی شد. با توجه به این که Context API آزمایشی بود، ا...

بهینه‌سازی برنامه‌های React در عمل برای افزایش سرعت

React می‌تواند کند باشد. منظورم این است که هر برنامه React با سایز متوسطی می‌تواند کند به نظر بیاید. اما قبل از این که به دنبال جایگزین بگردید، بهتر ا...

راهنمای سریع برای کمک به شما در درک و ساخت برنامه‌های ReactJS

اولین بخش، نحوه ساخت یک برنامه React ساده با استفاده از create-react-app را نشان داده و ساختار پروژه را شرح می‌دهد.بخش دوم یک قطعه کد که از قبل بر روی...

25 پروژه متن‌باز برتر Reactjs در سال اخیر

در این لیست، مجموعه‌ای با دقت برگزیده شده از میان تقریبا 8400 پروژه اوپن سورس را می‌بینید. برای انتخاب این موارد، محبوبیت، تعداد کاربران و جدید بودن آ...