ویژگیهای رندر، (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 از این مفهموم استفاده میکند.
نتیجه گیری
کار ما به اتمام رسیده است. ویژگیهای رندر استفاده مجدد از کد را بسیار ساده میکنند. به یاد داشته باشید، هر زمان که کامپوننتی میسازیم، میخواهیم در حد ممکن قابلیت استفاده مجدد را داشته باشد.
دیدگاه و پرسش
در حال دریافت نظرات از سرور، لطفا منتظر بمانید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید