تا این قسمت از سری جامع آموزش ری اکت توانسته ایم یک کامپوننت ساخته و داده خود را نمایش دهیم اما هنوز مشکلی وجود دارد. در اکثر اوقات داده های نمایش داده شده یک رشته ساده و ثابت نیستند بلکه داده های پویا هستند که بر اساس کاربر تغییر می کنند. به طور مثال به کامپوننت Person سری می زنیم و آن را به شکل زیر تغییر می دهیم:
const person = () => { return <p>I'm a person and I am X years old!</p> }
ما می خواهیم به جای X یک عدد نمایش دهیم. برای شروع می توانیم یک عدد تصادفی نمایش دهیم:
const person = () => { return <p>I'm a person and I am Math.floor(Math.random() * 30) years old!</p> }
در این کد از تابع math.floor استفاده کرده ایم تا عدد تصادفی خروجی (تابع math.random) اعشاری در نیاید و به سمت پایین گرد شود. اگر فایل Person را در همین حالت ذخیره کرده و به مرورگر برویم می بینیم که خروجی ما بدین شکل خواهد بود:
I'm a person and I am math.floor(math.random() * 30) years old!
I'm a person and I am math.floor(math.random() * 30) years old!
I'm a person and I am math.floor(math.random() * 30) years old!
به نظر شما چرا چنین اتفاقی رخ داده است؟ ما کدهای جاوا اسکریپت خود را در JSX نوشته ایم و react نمی داند که باید آن را به عنوان جاوا اسکریپت (و نه متن) پردازش کند. اگر در قسمت JSX خود داده های پویا داشته باشیم باید آن ها درون curly braces (علامت {}
) قرار دهیم. بنابراین می توان گفت:
const person = () => { return <p>I'm a person and I am {Math.floor(Math.random() * 30)} years old!</p> }
البته شما نمی توانید درون curly braces ها عناصر پیچیده ای مانند کلاس ها و ... را تعریف کنید، بلکه فقط می توان expression های ساده و تک خطی (مانند همین عدد تصادفی یا صدا زدن توابع) را در آن نوشت.
حالا به فایل App.js برگردید. می دانیم که می توانیم به عناصر HTML خصوصیات (attribute) مختلفی بدهیم مانند className. حالا اگر بخواهیم به Person چنین چیز هایی را اضافه کنیم چطور؟
class App extends Component { render() { return ( <div className="App"> <h1>Hi, I'm a React App!</h1> <p>This is really working!</p> <Person name="Max" age="28" /> <Person name="Manu" age="29" >My Hobbies: Racing</Person> <Person name="Stephanie" age="26" /> </div> ); // return React.createElement('div', {className: 'App'}, React.createElement('h1', null, 'Does this work now?')); } }
در اینجا ما به Person خصوصیات name و age را داده ایم. همچنین برای Person دوم تگ پایانی قرار داده ایم تا میان دو تگ عبارت My Hobbies: Racing را قرار دهیم. حالا اگر این فایل را ذخیره کنیم و به مرورگر مراجعه کنیم می بینیم که هیچ تغییری ایجاد نشده است. دلیل آن هم واضح است؛ react نمی داند با این اطلاعات چکار کند!
نکته جالب اینجاست که react این attribute ها را می گیرد و در شیء ای به نام props (مخفف properties) قرار می دهد. سپس ما می توانیم از طریق کامپوننت دریافت کننده، این اطلاعات را دریافت کرده و نمایش دهیم. react این شیء را به صورت آرگومان به تابع دریافتی ما در Person میفرستد بنابراین نیازی نیست که نام آرگومان را حتما props بگذارید (می توانید نام دلخواهتان را انتخاب کنید) اما برای راحت تر بودن یادگیری ما از همان props استفاده می کنیم:
const person = (props) => { return <p>I'm a person and I am {Math.floor(Math.random() * 30)} years old!</p> }
حالا باید اطلاعات دریافتی از شیء props را وارد JSX خود کنیم بنابراین:
const person = (props) => { return <p>I'm {props.name} person and I am {props.age} years old!</p> }
اگر فایل را ذخیره کرده و به مرورگر برویم نتیجه زیر را می بینیم:
I'm Max person and I am 28 years old!
I'm Manu person and I am 29 years old!
I'm Stephanie person and I am 26 years old!
بنابراین کد ما کار می کند!
نکته مهم: در جلسه قبل تفاوت کامپوننت های کاربردی (functional) و کامپوننت های کلاس-محور (class-based) را توضیح دادم و همانطور که می دانید کامپوننت ما (کامپوننت Person) از نوع کاربردی است. اگر کامپوننت شما از نوع class-based می باشد باید این عملیات را به صورت زیر انجام دهید:
class Person extends Component { render () { return <p>My name is {this.props}</p> } }
بنابراین به جای props.name می گوییم this.props
تصویر زیر خلاصه ای از این موضوع است. می توانید آن را در سیستم خود ذخیره کرده و هر از گاهی نگاهی به آن بیندازید تا مطالب را سریعا به یاد آورید:
حالا سوال دیگری پیش می آید. چرا قسمت My Hobbies نمایش داده نشد؟ آیا می توانیم آن را به شکل پویا تغییر دهیم؟ برای تغییر دادن اطلاعاتی که به شکل attribute (مانند name و age) وارد نشده اند و میان تگ های آغازین و پایانی کامپوننت قرار گرفته اند چه کاری باید کرد؟
برای انجام این کارها یک نوع props خاص وجود دارد که react آن را به ما می دهد. ابتدا باید کد return در کامپوننت Person را کمی تغییر دهیم:
const person = (props) => { return ( <p>I'm {props.name} person and I am {props.age} years old!</p> ) }
ابتدا کل کد را درون پرانتز گذاشته ایم. دلیل این کار را در جلسات قبل هم گفته بودیم؛ با این کار می توانید کدهای JSX را در چندین خط بنویسید (از اینتر استفاده کنید). سپس یک تگ <p> دیگر ایجاد کرده و هر دو را درون یک div قرار می دهیم:
const person = (props) => { return ( <div> <p>I'm {props.name} person and I am {props.age} years old!</p> <p></p> </div> ) }
حالا برای دسترسی به متن خودمان از props.children استفاده می کنیم:
const person = (props) => { return ( <div> <p>I'm {props.name} person and I am {props.age} years old!</p> <p>{props.children}</p> </div> ) }
نکات مهم:
با ذخیره کد بالا و رفتن به مرورگر با خروجی زیر مواجه می شویم:
I'm Max person and I am 28 years old!
I'm Manu person and I am 29 years old!
My Hobbies: Racing
I'm Stephanie person and I am 26 years old!
دانلود تمامی فایل های این پروژه تا این قسمت
امیدوارم که تا این قسمت با ما همراه بوده و مسائل عنوان شده را به خوبی درک کرده باشید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.