× خانه ویدیو دانلود اپلیکیشن درباره ما ورود / ثبت نام

  • خانه
  • ویدیو
  • دانلود
  • اپلیکیشن
  • درباره ما
  • ورود / ثبت نام
  • خانه
  • ویدیو
  • دانلود
  • اپلیکیشن
  • درباره ما
  • ورود / ثبت نام
خانه
|
پست های javascript
|
آموزش ساخت بازی XO با استفاده از React - بخش اول

مطالب

  • CSS
  • Git
  • HTML
  • Javascript
  • PHP
  • Web

بیشترین بازدید

  • طراحی صفحه ثبت نام و ورود کاربران HTML و CSS

    طراحی صفحه ثبت نام و ورود کاربران HTML و CSS

    با توجه به اینکه در سایت تبلیغات، کاربران جهت ارائه آگهی های خود باید ثبت نام کنند در این قسمت برای ارسال اطلاعات به سمت سرور، با استفاده از تگ های موجود در HTML فرمی را جهت ثبت نام و ورود کاربران ایجاد خواهیم کرد. در ادامه مطلب همراه من باشید. چیست و چه کاربردی دارد؟
  • ساخت وب سرویس با استفاده از PHP و SOAP

    ساخت وب سرویس با استفاده از PHP و SOAP

    به عنوان توسعه دهنده نرم افزار، توانایی توسعه نرم افزار و سرویس برای محدوده گسترده ای از پلتفرم ها یک مهارت ضروری است. اما برای تحقق این موضوع  نمی توان انتظار داشت که همه از یک پلتفرم یا یک زبان برنامه نویسی استفاده کنند یا اینکه همه پلتفرم ها و زبان ها را پوشش داد، این یک کار نشدنی است. اگر تنها یک استاندارد وجود داشت که به ما اجازه می داد تا کدهای نرم افزارمان را یکبار بنویسیم و دیگران با نرم افزارهای خودشان به آسانی از طریق شبکه با آن ارتباط برقرار می کردند چقدر عالی می شد. خب خوشبختانه وجود دارد و نامش هم  SOAP است. در ادامه مطلب همراه من باشید. چیست و چه کاربردی دارد؟
  • طراحی صفحه ثبت نام و ورود کاربران PHP و MySQL

    طراحی صفحه ثبت نام و ورود کاربران PHP و MySQL

    برای ثبت اطلاعات کاربران در پایگاه داده سایت، باید با استفاده از PHP اطلاعات ارسال شده توسط کاربر را دریافت کنیم و با استفاده از دستورات MySQL ذخیره کنیم. جهت اجرای کدهای PHP و MySQL در ویندوز باید نرم افزار WAMP یا XAMP را در سیستم خود نصب کنید. با استفاده از این نرم افزار یک لوکال هاست مجازی در سیستم شما شبیه سازی می شود تا کدهای PHP را اجرا و پایگاه داده MySQL را ایجاد کنید. در ادامه مطلب همراه من باشید. چیست و چه کاربردی دارد؟
  • ساخت وب سرویس RESTful با استفاده از PHP

    ساخت وب سرویس RESTful با استفاده از PHP

    Representational State Transfer یک سبک معماری در وب سرویس است که در آن از آدرس ها برای دستیابی به منابع استفاده می شود. داده ها و توابع در معماری RESTful منابع نامیده می شوند به این جهت که داده ها و توابع در واقع آنچیزی هستند که ما می خواهیم از طریق سرویس به آن متصل شویم. در این پست می خواهیم نشان دهیم که چطور می توان یک وب سرویس RESTful را بدون استفاده از هیچ نوع Framework خاصی در PHP ایجاد کرد. در ادامه مطلب همراه من باشید. چیست و چه کاربردی دارد؟
  • آموزش نصب و استفاده از Composer

    آموزش نصب و استفاده از Composer

    Composer ابزاری برای مدیریت وابستگی در پروژه های PHP می باشد. زمانی که شما تصمیم می گیرید تا یک پروژه PHP را ایجاد کنید قطعا با مسائلی برخورد خواهید کرد که راه حل آنها استفاده از کتابخانه ها یا پکیج های موجودی است که برای این مساله ها ارائه شده اند زیرا با این کار در فاکتور های مهمی همچون زمان و هزینه صرفه جویی کرده اید و به عبارت دیگر چرخ را از نو اختراع نمی کنید. از این دست مسائل می توان به: اعتبار سنجی کاربر مدیریت پایگاه داده مسیریابی درخواست اشاره کرد. اما در این میان کتابخانه ها یا پکیج های موجود هم دارای وابستگی های خاص خود هستند و به عنوان توسعه دهنده PHP شما باید انرژی مضاعفی را برای یافتن و تطبیق این وابستگی ها صرف کنید. در ادامه مطلب همراه من باشید. چیست و چه کاربردی دارد؟
  • ساخت WSDL با استفاده از PHP

    ساخت WSDL با استفاده از PHP

    در قسمت قبل ایجاد یک اپلیکیشن سازگار را با استفاده از پروتکل SOAP بررسی کردیم. همینطور نشان دادیم که ساخت سرور و کلاینت SOAP با کتابخانه NuSOAP چقدر آسان است اما در این قسمت می خواهیم WSDL را که در هنگام کار با SOAP حتما استفاده خواهد شد را توضیح دهیم. در اینجا ما در ارتباط با فایل های WSDL و اینکه چطور می توان از آنها استفاده کرد بحث خواهیم کرد همچنین به شما نشان می دهیم که به چه صورت می توان فایل WSDL  را با NuSOAP ایجاد کنید و آن را با مثال های سرور و کلاینت SOAP که در قسمت قبل ایجاد کردیم ترکیب کنیم. در ادامه مطلب همراه من باشید. چیست و چه کاربردی دارد؟
تبلیغات

دانلودها

  • آموزش لاراول: معرفی و آموزش گام به گام Laravel
  • آموزش ساخت بازی XO با استفاده از React - بخش دوم
  • آموزش ساخت بازی XO با استفاده از React - بخش اول
  • آموزش React - قسمت سوم
  • آموزش React - قسمت دوم

سوالات

  • اضافه کردن یک ستون جدید به جدول موجود در Migration لاراول

    چطور می توانم یک ستون به جدولی که از قبل با استفاده از فریموورک لاراول ایجاد شده است اضافه کنم؟من فایل Migration رو به صورت زیر ویرایش کردم:<?php public function up() { Schema::create('users', function ($table) { $table->integer("paid"); }); }در ترمینال هم دستور php artisan migrate:install  و migrate رو اجرا کردم، اما ستون اضافه نشده است.چطور می توانم ستون مورد نظرم را اضافه کنم؟
  • چک کردن موجود بودن یک رکورد در Laravel

    من تازه کار با فریممورک Laravel رو شروع کردم. چطور می توانم بررسی کنم که یک رکورد موجود است یا خیر؟$user = User::where('email', '=', Input::get('email'));چطور می می تونم بررسی کنم که user$ شامل رکورد هست یا نه؟
  • لاراول 4: چطور می توان در Blade آدرس صفحه را دریافت کرد؟

    من از لاراول نسخه 4 استفاده می کنم، چطور می توانم آدرس یک صفحه را دریافت کنم و در if@ استفاده کنم. می دونم که  می توانم با استفاده از کد PHP زیر این کار را انجام دهم:<?php echo URL::current(); ?>اما در blade چطور می توان این کار را انجام داد؟
  • چطور می توان چندین شرط Where در Eloquent لاراول در نظر گرفت؟

    من از Query Builder لاراول برای ایجاد گزارش استفاده می کنم و گزارشم دارای چندین شرط می باشد.شرط ها را به صورت زیر اعمال کردم اما به نظرم راه جالبی نیست.$results = User::where('this', '=', 1) ->where('that', '=', 1) ->where('this_too', '=', 1) ->where('that_too', '=', 1) ->where('this_as_well', '=', 1) ->where('that_as_well', '=', 1) ->where('this_one_too', '=', 1) ->where('that_one_too', '=', 1) ->where('this_one_as_well', '=', 1) ->where('that_one_as_well', '=', 1) ->get();آیا راه بهتری برای اعمال شرط ها وجود دارد؟
  • چطور می توان گزارش SQL که Query Builder لاراول آن را ایجاد می کند مشاهده کرد؟

    کد زیر را در نظر بگیرید:DB::table('users')->get();من می خوام کد SQL که Query Builder بالا اجرا می کند را دریافت کنم به عنوان مثال در کد بالا کد SQL:SELECT * FROM usersتوسط Query builder اجرا می شود.
  • Eloquent: شمارش و تشخیص خالی بودن

    آیا راهی برای تشخیص اینکه مجموعه بازگشتی از گزارش:$result = Model::where(...)->get() خالی است یا اینکه تعداد عناصر موجود در آن چقدر است وجود دارد؟من در حال حاضر از:!$result استفاده می کنم آیا راه درستی است؟در مورد:count($result)آیا همه موارد را پوشش می دهد؟ به عنوان مثال اگر result خالی باشد؟
  • لاراول 5: نمایش HTML در Blade

    من یک رشته به صورت زیر دارم که شامل تگ HTML می باشد:$text = '<p><strong>Lorem</strong> ipsum dolor <img src="images/test.jpg"></p>'و می خواهم با استفاده از Blade نمایش بدم:{{$text}}اما خود رشته را چاپ می کند و تگ های HTML را رندر نمی کند. چطور می توانم HTML را با Blade در لاراول 5 نمایش بدم؟
  • ReactJSX: استفاده از Props بین کوتیشن

    چطور می توان در JSX از یک مقدار props به عنوان مقدار attribute استفاده کرد؟به عنوان مثال:<img className="image" src="images/{this.props.image}" />و خروجی HTML آن به صورت زیر است:<img class="image" src="images/{this.props.image}"> 
  • ارتباط بین دو کامپوننت در React

    اپلیکیشن من شامل یک لیست با فیلتر های آن و یک button برای تغییر layout می باشد. در حال حاضر از سه کامپوننت:</list></Filters></TopBar>استفاده می کنم. می خوام زمانی که تنظیمات در </Filters> تغییر کرد متدی در کامپوننت </list> برای بروزرسانی view اجرا شود.چطور میتونم بین این سه کامپوننت ارتباط برقرار کنم؟ آیا باید از مدل داده global برای انجام این کار استفاده کنم؟ 
  • Show یا Hide کردن عنصر در React

    من تازه شروع به یادگیری React کردم و دنبال راهی هستم که بتونم یک عنصر روی صفحه را show یا hide کنم.  می خوام زمانی که کلیک کردم، div مربوط به نتایج نمایش داده شود.var Search= React.createClass({ handleClick: function (event) { console.log(this.prop); }, render: function () { return ( <div className="date-range"> <input type="submit" value="Search" onClick={this.handleClick} /> </div> ); } }); var Results = React.createClass({ render: function () { return ( <div id="results" className="search-results"> Some Results </div> ); } }); React.renderComponent(<Search /> , document.body); 

اشتراک

آموزش ساخت بازی XO با استفاده از React - بخش اول

آموزش ساخت بازی XO با استفاده از React - بخش اول

۱۴ فروردین ۱۳۹۸
دانیال افشار
1592

در این پست می خواهیم با استفاده از کتابخانه React،  بازی XO را ایجاد کنیم. تکنیک هایی که شما در این پست فرا می گیرید اساس ساخت هر برنامه React است و تسلط  بر آن باعث ایجاد درک عمیق از این کتابخانه می شود.

این آموزش به بخش های زیر تقسیم می شود:

  • آماده سازی اولیه برای شروع  پروژه

  • بررسی اصول اولیه React شامل state، props و Component

  • توسعه پروژه بازی که طی آن با اغلب تکنیک های رایج توسعه اپلیکیشن های مبتنی بر React آشنا خواهید شد

  • اضافه کردن Time travel که باعث ایجاد درک عمیق تر نسبت به نقاط قوت React خواهد شد.

در ادامه مطلب همراه من باشید.

می توانید این پروژه را به صورت کامل از این لینک دریافت کنید. اگر با کدها آشنا نیستید نگران نباشید هدف این پست کمک به شما در درک React و syntax آن می باشد.

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

از طراحی قالب ساده بازی در این آموزش شروع می کنیم و فرض می کنیم که شما با HTML، Javascript و مفاهیم برنامه نویسی مانند: function، object، آرایه و کمی هم با کلاس ها آشنا هستید.

توجه داشه باشید که در این آموزش از برخی ویژیگی های ES6 )نسخه آخر جاوااسکریپت( مانند: arrow function، class، let و const استفاده می کنیم. علاوه بر این شما می توانید از BabelREPL جهت بررسی اینکه کد ES6 به چه کدی کامپایل می شود استفاده کنید.

React چیست؟

یک کتابخانه منعطف و تاثیرگذار که مبتنی بر جاوااسکریپت می باشد و برای ساخت رابط های کاربری از آن استفاده می شود. پارادایم این کتابخانه از نوع اعلانی می باشد و به شما این امکان را می دهد تا UI های پیچیده را با استفاده از قسمت های مستقل و کوچکتر که کامپوننت نامیده می شوند ایجاد کنید.

چند نوع کامپوننت در React وجود دارد که با زیر کلاس React.Component شروع می کنیم:

class ShoppingList extends React.Component {
  render() {
    return (
      <div className="shopping-list">
        <h1>Shopping List for {this.props.name}</h1>
        <ul>
          <li>Instagram</li>
          <li>WhatsApp</li>
          <li>Oculus</li>
        </ul>
      </div>
    );
  }
}

کامپوننت ها برای توصیف چیزی که می خواهیم در صفحه نمایش مشاهده کنیم استفاده می شوند. همچنین زمانی که داده های کامپوننت تغییر می کند، مجددا رندر و به روز رسانی می شود.

در اینجا ShopingList یک React component class یا React component type می باشد. یک کامپوننت پارامترهایی که props (کوتاه شده properties)  نامیده می شود را دریافت می کند و سلسله مراتبی از view ها  را با استفاده از متد render نمایش می دهد.

متد render شامل توصیف آنچیزی است که می خواهیم روی صفحه، نمایش دهیم. React توصیف را دریافت و نتیجه را نمایش می دهد. متد render یک React element را بر می گرداند که در واقع همان توصیفی است که پیشتر در ارتباط با آن توضیح دادیم. اکثر توسعه دهنده های React از Syntax خاصی به نام JSX استفاده می کنند که ساختار کد را ساده تر می کند. به عنوان مثال در JSX،  <div/> به React.createElement(‘div’)  تبیدل می شود. مثال بالا معادل با:

return React.createElement('div', {className: 'shopping-list'},
  React.createElement('h1', /* ... h1 children ... */),
  React.createElement('ul', /* ... ul children ... */)
);

می باشد.

در JSX می توانیم از هر عبارت جاوااسکریپت بین آکولاد استفاده کنیم. هر عنصر React یک شی جاوااسکریپت است و می توان آن را در متغیر ذخیره کرد یا از آن در جای دیگری از برنامه استفاده کرد.

در کد بالا کامپوننت ShopingList تنها عناصر DOM مانند <div/> و <li/> را render می کند علاوه بر این می توان کامپوننت های React را ترکیب و render کرد. برای مثال می توانیم از طریق تگ <ShopingList/>  در کامپوننت های دیگر به این کامپوننت دسترسی داشته باشیم. هر کامپوننت React به صورت بسته بندی شده می باشد و می تواند به صورت مستقل عمل کند و این مورد به ما اجازه می دهد تا UI های پیچیده را با استفاده از کامپوننت ها، ساده تر ایجاد کنیم.

بررسی کد شروع

ابتدا یک فایل HTML ایجاد می کنیم و نام آن را index قرار می دهیم و کدهای زیر را در آن وارد می کنیم:

<!DOCTYPE html>
<html lang="en" >
<head>
    <meta charset="UTF-8">
    <title>Tic Tac Toe</title>
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
    <div id="errors" style="background: #c00;color: #fff;display: none;margin: -20px -20px 20px;padding: 20px;white-space: pre-wrap;">
    </div>
    <div id="root">
    </div>
    <script src='js/react-development.js'></script>
    <script src='js/react-dom-development.js'></script>
    <script src="js/index.js"></script>
</body>
</html>

در پوشه پروژه سپس پوشه js، فایل index.js را باز کنید. در این آموزش ما سه کامپوننت خواهیم داشت:

  • Square
  • Board
  • Game

Square کامپوننت یک عنصر <button>، کامپوننت Board تعداد 9 کامپوننت Square و کامپوننت Game هم کامپوننت Board را با مقادیر placeholder که بعدا آن را ویرایش می کنیم render می کنند. تا اینجا هیچ کامپوننت محاوره ای وجود ندارد.

ارسال داده از طریق Props

در متد renderSquare کامپوننت Board، برای ارسال یک prop به کلاس Square که نام آن value می باشد، کد را به صورت زیر تغییر می دهیم:

class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;
  }

همچنین متد render کامپوننت Square را به صورت زیر تغییر می دهیم:

class Square extends React.Component {
  render() {
    return (
      <button className="square">
        {this.props.value}
      </button>
    );
  }
}

تغییرات اعمال شده به صورت زیر است:

قبل از ارسال value:

بعد از ارسال value:

تا اینجا توانستیم یک prop را از کامپوننت والد یعنی Board به کامپوننت فرزند یعنی Square ارسال کنیم.

ایجاد کامپوننت محاوره ای

حالا می خواهیم زمانی که روی Square کلیک شد این کامپوننت با یک حرف “X” پر شود.  ابتدا کد render کامپوننت Square را به صورت زیر تغییر می دهیم:

class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { alert('click'); }}>
        {this.props.value}
      </button>
    );
  }
}

نکته:

به منظور حجم کمتر کد و جلوگیری از سردرگمی در رفتار this از arrow function برای event handler استفاده می کنیم.

class Square extends React.Component {
 render() {
   return (
     <button className="square" onClick={() => alert('click')}>
       {this.props.value}
     </button>
   );
 }
}

توجه داشته باشید که چگونه به جای onClick={() => alert('click')}، یک تابع را برای onClick قرار دادیم. این تابع فقط در زمان کلیک اجرا می شود. فراموش کردن ()=> و نوشتن onClick={alert('click')} یک اشتباه رایج است و هر بار که کامپوننت، مجددا render شود این تابع اجرا می شود.

حال اگر روی Square کلیک کنیم یک alert در مرورگر نمایش داده می شود.

در قدم بعدی می خواهیم کامپوننت Square حالت خود را حفظ کند (با “X” پر شده است یا نه). برای حفظ  کردن یا به خاطر داشتن هر چیزی در React از state استفاده می کنیم.

کامپوننت های React می توانند با تنظیم this.state در constructor مربوط به خودشان حالت خود را نگهداری کنند. this.state ها به صورت خصوصی در کامپوننت تعریف می شوند و کامپوننت های دیگر به آن دسترسی ندارند. حالا می توانیم مقدار جاری کامپوننت Square را در this.state ذخیره کنیم و زمانی که Square کلیک شد آن را تغییر دهیم.

ابتدا ما متد constructor را به صورت زیر به کامپوننت Square اضافه می کنیم:

class Square extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: null,
    };
  }

  render() {
    return (
      <button className="square" onClick={() => alert('click')}>
        {this.props.value}
      </button>
    );
  }
}

نکته:

به خاطر داشته باشید که درزیر کلاس های جاوااسکریپت (کلاس هایی که extend شده اند) زمانی که constructor را تعریف می کنید باید super را در constructor فراخوانی کنید. همه کلاس های React.Component که دارای constructor می باشند باید با فراخوانی super(props) آغاز شوند.

حالا جهت نمایش مقدار state کامپوننت Square در زمان کلیک شدن،  متد render این کامپوننت را به صورت زیر تغییر می دهیم.

  • جایگزین کردن this.props.value به جای this.state.value در تگ button
  • جایگزین کردن ()=> alert() با ()=> this.setState({value:’X’}) در onClick
  • className و onClick را در 2 خط جدا قرار دادیم تا کد ما از خوانایی بالاتری برخوردار باشد

پس از اعمال تغییرات، تگ <button> که توسط متد render کامپوننت Square بازگردانده می شود باید به صورت زیر باشد:

class Square extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: null,
    };
  }

  render() {
    return (
      <button
        className="square"
        onClick={() => this.setState({value: 'X'})}
      >
        {this.state.value}
      </button>
    );
  }
}

در واقع ما با فراخوانی this.setState از onClick در متد render کامپوننت Square به React اعلام می کنیم که هر زمان که روی <button> کلیک شد، کامپوننت Square را render مجدد کند. پس از به روز رسانی، this.state.value برابر با ‘X’ می شود و می توانیم آن را روی Borad بازی ببینیم. اگر روی هر Square کلیک کنیم ‘X’ نمایش داده می شود.

زمانی که شما setState را در یک کامپوننت فراخوانی می کنید React به صورت خودکار همه کامپوننت های فرزند داخل آن کامپوننت را به روز می کند.

ابزار توسعه دهنده

افزونه React Devtools برای مرورگرهای Chrome و Firefox این امکان را به ما می دهد تا درخت کامپوننت های React را ردیابی کنیم. پس از نصب افزونه و برای مشاهده آن، در صفحه مرورگر کلیک راست کرده و گزینه Inspect element را انتخاب کنید، تب آخر مربوط به افزونه React Devtools می باشد.

همچنین می توانید در React Devtools مقادیر props و state های مربوط به کامپوننت های React را چک کنید.

ادامه توسعه بازی

حالا بلاک های پایه بازی XO را ایجاد کردیم. برای تکمیل بازی نیاز داریم تا “X” و “O” به شکل متناوب در Borad بازی قرار بگیرند و پس از آن برنده بازی را مشخص کنیم.

انتقال State به سطح بالاتر

در حال حاضر هر Square حالت بازی را جداگانه نگهداری می کند. برای مشخص کردن برنده بازی باید مقدار هر 9 Square را در یک جا نگهداری کنیم.

کامپوننت Board می تواند از هر Square مقدار State را درخواست کند، با اینکه این روش در React امکان پیاده سازی دارد اما باعث پیچیده شدن کد و کاهش خوانایی آن می شود و کد ما مستعد ایجاد باگ خواهد شد. می توانیم حالت بازی را در کامپوننت والد یعنی Board به جای هر Square نگهداری کنیم. کامپوننت Borad می تواند با ارسال Prop به هر Square مشخص کند که چه چیزی باید در Square نمایش داده شود، دقیقا مانند ارسال یک عدد از طریق Prop به Square که پیش تر انجام دادیم.

برای جمع آوری داده از چندین فرزند، یا داشتن ارتباط بین دو فرزند، باید یک state اشتراکی در کامپوننت والد تعریف کنیم. کامپوننت والد می تواند با استفاده از props، state را به فرزندان برگرداند که باعث همگام سازی کامپوننت های فرزند با یکدیگر و همچنین کامپوننت والد می شود.

یک تابع constructor به کامپوننت Borad اضافه می کنیم و حالت اولیه state را برابر با یک آرایه 9 قسمتی که همه آنها null می باشد قرار می دهیم.

class Board extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      squares: Array(9).fill(null),
    };
  }

  renderSquare(i) {
    return <Square value={i} />;
  }

بعدا زمانی که بازی را شروع کردیم آرایه this.state.squares کامپوننت Borad  به صورت زیر خواهد بود:

[
  'O', null, 'X',
  'X', 'X', 'O',
  'O', null, null,
]

متد renderSquare کامپوننت Borad به صورت زیر خواهد بود.

renderSquare(i) {
   return <Square value={i} />;
}

در ابتدای آموزش مقادیر را از کامپوننت Board به کامپوننت Square ارسال کردیم تا اعداد را نمایش دهد. حالا در اینجا ما اعداد را با نشانه “X” که توسط حالت Square مشخص شده جایگذاری می کنیم. به همین دلیل است که کامپوننت Square مقدار ارسال شده توسط Board را نادیده می گیرد.

در اینجا دوباره از مکانیسم ارسال prop استفاده می کنیم و کامپوننت Board را برای ساخت Square با مقدار جاری خودش یعنی ‘X’، ‘O’ یا null تغییر می دهیم. در حال حاضر آرایه squares را در constructor کامپوننت Board تعریف کردیم و حالا باید متد renderSquare را برای خواندن از آن تغییر دهیم.

renderSquare(i) {
    return <Square value={this.state.squares[i]} />;
}

حالا هر Square یک prop به نام value دریافت می کند که می تواند ‘X’، ‘O’ یا null برای Square های خالی باشد.

در قدم بعد، ما باید عملی که در زمان کلیک Square انجام می شده را تغییر دهیم. در حال حاضر کامپوننت Board، Square هایی را که پر شده است را نگهداری می کند. ما باید از کامپوننت Square مقادیر State کامپوننت Borad را به روز رسانی کنیم. از آنجایی که State در کامپوننتی  که تعریف می شود به صورت خصوصی است نمی توانیم به صورت مستقیم از Square، مقدار State کامپوننت Board را تغییر دهیم.

برای حفظ محرمانگی state کامپوننت Borad، ما یک function را از کامپوننت Board به Square ارسال می کنیم. این تابع زمانی فراخوانی می شود که Square کلیک شده باشد. متد renderSquare در کلاس Borad  را به صورت زیر تغییر می دهیم:

  renderSquare(i) {
    return (
      <Square
        value={this.state.squares[i]}
        onClick={() => this.handleClick(i)}
      />
    );
  }

حالا دو props را از کامپوننت Board به Square ارسال می کنیم (value و onClick). در واقع onClick تابعی است که کامپوننت Square می تواند در زمان کلیک فراخوانی کند. سپس تغییرات زیر را در کامپوننت Square اعمال می کنیم.

  • جایگزین کردن this.state.value با this.props.value در متد render کامپوننت Square
  • جایگزین کردن this.setState با this.props.onClick در متد render کامپوننت Square
  • حذف constructor از کامپوننت Square به علت عدم وجود State در این کامپوننت

پس از اعمال تغییرات کامپوننت Square به شکل زیر خواهد بود:

class Square extends React.Component {
  render() {
    return (
      <button
        className="square"
        onClick={() => this.props.onClick()}
      >
        {this.props.value}
      </button>
    );
  }
}

زمانی که Square کلیک می شود، تابع onClick ارائه شده توسط کامپوننت Board فراخوانی می شود. در اینجا این مورد را بیشتر بررسی می کنیم:

1. onClick مربوط به <button> به React اعلام می کند که یک click event listener در نظر بگیرد.

2. React زمانی که button کلیک می شود، onClick که در متد render کامپوننت Square تعریف شده است را فراخوانی می کند.

3.در اینجا this.props.onClick() فراخوانی می شود. onClick کامپوننت Square توسط کامپوننت Board تعریف شده است.

4. کامپوننت Board onClick={() => this.handleClick(i)} را به کامپوننت Square ارسال کرده است و Square زمانی که کلیک می شود this.handleClick(i) را فراخوانی می کند.

5. البته ما هنوز handleClick() را تعریف نکردیم و زمانی که روی Square کلیک می کنیم، با خطا مواجه می شویم که دلیل آن عدم تعریف متد handleClick در کامپوننت Board است. در اینجا ما به صورت زیر این متد را به کامپوننت Borad اضافه می کنیم:

class Board extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      squares: Array(9).fill(null),
    };
  }

  handleClick(i) {
    const squares = this.state.squares.slice();
    squares[i] = 'X';
    this.setState({squares: squares});
  }

  renderSquare(i) {
    return (
      <Square
        value={this.state.squares[i]}
        onClick={() => this.handleClick(i)}
      />
    );
  }

  render() {
    const status = 'Next player: X';

    return (
      <div>
        <div className="status">{status}</div>
        <div className="board-row">
          {this.renderSquare(0)}
          {this.renderSquare(1)}
          {this.renderSquare(2)}
        </div>
        <div className="board-row">
          {this.renderSquare(3)}
          {this.renderSquare(4)}
          {this.renderSquare(5)}
        </div>
        <div className="board-row">
          {this.renderSquare(6)}
          {this.renderSquare(7)}
          {this.renderSquare(8)}
        </div>
      </div>
    );
  }
}

پس از این تغییرات، جهت پر شدن Square دوباره روی آن کلیک می کنیم و اینبار خطا برطرف شده است. علاوه بر این state به جای کامپوننت Square در کامپوننت Board ذخیره می شود. زمانی که state مربوط به کامپوننت Board تغییر می کند، Square به صورت خودکار render مجدد می شود. نگهداری همه state های مربوط به Square ها در Board به ما این امکان را می دهد تا در ادامه برنده بازی را مشخص کنیم.

با توجه به اینکه کامپوننت Square از این به بعد state را نگهداری نمی کند، مقادیر مربوط به state را از کامپوننت Board درخواست می کند و زمانی که کلیک می شود به کامپوننت Borad اطلاع می دهد. در React به کامپوننت هایی مانند Square، کامپوننت کنترلی گفته می شود و کامپوننت Borad کنترل کاملی بر آنها دارد.

توجه داشته باشید که در متد handleClick، تابع slice را برای کپی آرایه square فراخوانی کردیم، تا به جای آرایه موجود، آرایه کپی شده را ویرایش کنیم. در قسمت بعدی توضیح خواهیم داد چرا یک کپی از آرایه squaers ایجاد کردیم.

چرا تغییر ناپذیری مهم است

در قسمت قبل ما از تابع slice() برای ایجاد یک کپی از آرایه squares استفاده کردیم و به جای  ویرایش مستقیم آرایه squares، کپی آن را ویرایش کردیم. در اینجا قصد داریم بررسی کنیم که تغییر ناپذیری چیست و چرا حائز اهمیت است.

به طور کلی دو روش برای تغییر داده وجود دارد. اولین روش تغییر داده به طور مستقیم است. دومین روش جایگزین کردن و تغییر دلخواه، در کپی داده است.

تغییر داده به صورت مستقیم

var player = {score: 1, name: 'Jeff'};
player.score = 2;
// Now player is {score: 2, name: 'Jeff'}

تغیییر داده به صورت غیر مستقیم

var player = {score: 1, name: 'Jeff'};

var newPlayer = Object.assign({}, player, {score: 2});
// Now player is unchanged, but newPlayer is {score: 2, name: 'Jeff'}

// Or if you are using object spread syntax proposal, you can write:
// var newPlayer = {...player, score: 2};

نتیجه نهایی هر دو یکسان می باشد اما روش غیر مستقیم دارای مزایای زیر می باشد:

ویژیگی های پیچیده ساده می شوند

تغییر ناپذیری، پیاده سازی ویژیگی های پیچیده را بسیار آسان تر می کند. در ادامه قصد داریم تا ویژگی Time Travel را که امکان بررسی تاریخچه بازی و بازگشت به حرکات قبلی را فراهم می کند پیاده سازی کنیم. این قابلیت مختص بازی ها نیست وبیشتر به صورت ویژگی  Undo و Redo در اپلیکیشن ها موجود می باشد. با عدم استفاده از ویرایش مستقیم داده می توانیم تاریخچه بازی را نگهداری کنیم و بعدا از آن استفاده کنیم.

ردیابی تغییرات

ردیابی تغییرات در object های تغییر پذیر مشکل تر است زیرا به صورت مستقیم ویرایش شده است و در این صورت جهت ردیابی تغییرات باید object تغییر پذیر را با نسخه های کپی قبلی خودش مقایسه کنیم و کل درخت object پیمایش شود.

ردیابی تغییرات در object های تغییر ناپذیر به مراتب آسان تر می باشد. اگر object تغییر ناپذیری که به آن ارجاع داده شده با object قبلی تفاوت داشته باشد بنابراین object تغییر کرده است.

تعیین زمان render مجدد در React

با استفاده از تغییر داده به صورت غیر مستقیم می توانیم pure component  را در React ایجاد کنیم. و در صورت تغییر object می توان به آسانی مشخص  کرد که کامپوننت  نیاز به render مجدد دارد.

کامپوننت های تابعی

در این قسمت قصد داریم تا کامپوننت Square را به یک کاپوننت تابعی تبدیل کنیم.

در React، کامپوننت تابعی راه ساده ای برای نوشتن کامپوننت هایی است که فقط دارای متد render هستند و state ندارند. به جای تعریف کلاس و ارث بری از React.Component، می توانیم یک تابع تعریف کنیم که props را به عنوان ورودی دریافت می کند و چیزی که باید render شود را باز می گرداند. کامپوننت های تابعی از لحاظ حجم کد نسبت به کلاس ها سبک تر هستند و می توان آن ها را راحت تر ایجاد کرد. بسیاری از کامپوننت ها از این طریق ایجاد می شوند.

کلاس Square را با تابع زیر جایگزین کنید.

function Square(props) {
  return (
    <button className="square" onClick={props.onClick}>
      {props.value}
    </button>
  );
}

در این کد this.props به props تغییر کرده است.

نکته

زمانی که ما Square را تغییر دادیم و آن را به یک کامپوننت تابعی تبدیل کردیم، onClick={() => this.props.onClick()}  را به onClick={props.onClick} تغییر دادیم (توجه داشته باشید که پرانتزهای هر دو طرف حذف شده). در کلاس ما از arrow function برای دسترسی به مقدار this استفاده کردیم اما در کامپوننت تابعی ما نیازی به this نخواهیم داشت.

تعیین نوبت

در این قسمت نقص آشکار در بازی را برطرف می کنیم. در بازی ما “O” نمی تواند روی Board بازی قرار بگیرد و با هربار کلیک فقط نشانه "X" روی Board قرار می گیرد.

ما به صورت پیش فرض اولین حرکت را “X” قرار دادیم که می توان با تغییر state در متد constructor کامپوننت Board آن را تغییر بدهیم.

class Board extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      squares: Array(9).fill(null),
      xIsNext: true,
    };
  }

هر بار کاربر حرکت می کند متغیر xIsNext که از نوع Boolean می باشد تغییر می کند و طبق مقدار این متغیر نوبت بعدی یعنی بازیگر “X” یا “O” تعیین و state بازی ذخیره می شود. حالا ما باید تابع handleClick را برای تغییر مقدار xIsNext تغییر دهیم.

  handleClick(i) {
    const squares = this.state.squares.slice();
    squares[i] = this.state.xIsNext ? 'X' : 'O';
    this.setState({
      squares: squares,
      xIsNext: !this.state.xIsNext,
    });
  }

با این تغییر “X” و “O” می توانند نوبت خود را دریافت کنند. حالا باید متن status را در متد render کامپوننت Board تغییر دهیم که به ما نشان می دهد نوبت حرکت کدام بازیکن است.

  render() {
    const status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');

    return (
      // the rest has not changed

پس از اعمال تغییرات، کامپوننت Borad باید به شکل زیر باشد:

class Board extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      squares: Array(9).fill(null),
      xIsNext: true,
    };
  }

  handleClick(i) {
    const squares = this.state.squares.slice();
    squares[i] = this.state.xIsNext ? 'X' : 'O';
    this.setState({
      squares: squares,
      xIsNext: !this.state.xIsNext,
    });
  }

  renderSquare(i) {
    return (
      <Square
        value={this.state.squares[i]}
        onClick={() => this.handleClick(i)}
      />
    );
  }

  render() {
    const status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');

    return (
      <div>
        <div className="status">{status}</div>
        <div className="board-row">
          {this.renderSquare(0)}
          {this.renderSquare(1)}
          {this.renderSquare(2)}
        </div>
        <div className="board-row">
          {this.renderSquare(3)}
          {this.renderSquare(4)}
          {this.renderSquare(5)}
        </div>
        <div className="board-row">
          {this.renderSquare(6)}
          {this.renderSquare(7)}
          {this.renderSquare(8)}
        </div>
      </div>
    );
  }
}

در بخش بعدی آموزش تابعی را برای تعیین برنده بازی ایجاد می کنیم و ویژیگی های بیشتری را به بازی اضافه می کنیم.

منبع: reactjs.org

ReactJavascript

مطالب مرتبط

آموزش ساخت بازی XO با استفاده از React - بخش دوم
مشاهده

آموزش ساخت بازی XO با استفاده از React - بخش دوم

آموزش React - قسمت سوم
مشاهده

آموزش React - قسمت سوم

آموزش React - قسمت دوم
مشاهده

آموزش React - قسمت دوم



نظر شما

مطالب

  • CSS
  • Git
  • HTML
  • Javascript
  • PHP
  • Web

بیشترین بازدید

  • طراحی صفحه ثبت نام و ورود کاربران HTML و CSS

    طراحی صفحه ثبت نام و ورود کاربران HTML و CSS

    با توجه به اینکه در سایت تبلیغات، کاربران جهت ارائه آگهی های خود باید ثبت نام کنند در این قسمت برای ارسال اطلاعات به سمت سرور، با استفاده از تگ های موجود در HTML فرمی را جهت ثبت نام و ورود کاربران ایجاد خواهیم کرد. در ادامه مطلب همراه من باشید. چیست و چه کاربردی دارد؟
  • ساخت وب سرویس با استفاده از PHP و SOAP

    ساخت وب سرویس با استفاده از PHP و SOAP

    به عنوان توسعه دهنده نرم افزار، توانایی توسعه نرم افزار و سرویس برای محدوده گسترده ای از پلتفرم ها یک مهارت ضروری است. اما برای تحقق این موضوع  نمی توان انتظار داشت که همه از یک پلتفرم یا یک زبان برنامه نویسی استفاده کنند یا اینکه همه پلتفرم ها و زبان ها را پوشش داد، این یک کار نشدنی است. اگر تنها یک استاندارد وجود داشت که به ما اجازه می داد تا کدهای نرم افزارمان را یکبار بنویسیم و دیگران با نرم افزارهای خودشان به آسانی از طریق شبکه با آن ارتباط برقرار می کردند چقدر عالی می شد. خب خوشبختانه وجود دارد و نامش هم  SOAP است. در ادامه مطلب همراه من باشید. چیست و چه کاربردی دارد؟
  • طراحی صفحه ثبت نام و ورود کاربران PHP و MySQL

    طراحی صفحه ثبت نام و ورود کاربران PHP و MySQL

    برای ثبت اطلاعات کاربران در پایگاه داده سایت، باید با استفاده از PHP اطلاعات ارسال شده توسط کاربر را دریافت کنیم و با استفاده از دستورات MySQL ذخیره کنیم. جهت اجرای کدهای PHP و MySQL در ویندوز باید نرم افزار WAMP یا XAMP را در سیستم خود نصب کنید. با استفاده از این نرم افزار یک لوکال هاست مجازی در سیستم شما شبیه سازی می شود تا کدهای PHP را اجرا و پایگاه داده MySQL را ایجاد کنید. در ادامه مطلب همراه من باشید. چیست و چه کاربردی دارد؟
  • ساخت وب سرویس RESTful با استفاده از PHP

    ساخت وب سرویس RESTful با استفاده از PHP

    Representational State Transfer یک سبک معماری در وب سرویس است که در آن از آدرس ها برای دستیابی به منابع استفاده می شود. داده ها و توابع در معماری RESTful منابع نامیده می شوند به این جهت که داده ها و توابع در واقع آنچیزی هستند که ما می خواهیم از طریق سرویس به آن متصل شویم. در این پست می خواهیم نشان دهیم که چطور می توان یک وب سرویس RESTful را بدون استفاده از هیچ نوع Framework خاصی در PHP ایجاد کرد. در ادامه مطلب همراه من باشید. چیست و چه کاربردی دارد؟
  • آموزش نصب و استفاده از Composer

    آموزش نصب و استفاده از Composer

    Composer ابزاری برای مدیریت وابستگی در پروژه های PHP می باشد. زمانی که شما تصمیم می گیرید تا یک پروژه PHP را ایجاد کنید قطعا با مسائلی برخورد خواهید کرد که راه حل آنها استفاده از کتابخانه ها یا پکیج های موجودی است که برای این مساله ها ارائه شده اند زیرا با این کار در فاکتور های مهمی همچون زمان و هزینه صرفه جویی کرده اید و به عبارت دیگر چرخ را از نو اختراع نمی کنید. از این دست مسائل می توان به: اعتبار سنجی کاربر مدیریت پایگاه داده مسیریابی درخواست اشاره کرد. اما در این میان کتابخانه ها یا پکیج های موجود هم دارای وابستگی های خاص خود هستند و به عنوان توسعه دهنده PHP شما باید انرژی مضاعفی را برای یافتن و تطبیق این وابستگی ها صرف کنید. در ادامه مطلب همراه من باشید. چیست و چه کاربردی دارد؟
  • ساخت WSDL با استفاده از PHP

    ساخت WSDL با استفاده از PHP

    در قسمت قبل ایجاد یک اپلیکیشن سازگار را با استفاده از پروتکل SOAP بررسی کردیم. همینطور نشان دادیم که ساخت سرور و کلاینت SOAP با کتابخانه NuSOAP چقدر آسان است اما در این قسمت می خواهیم WSDL را که در هنگام کار با SOAP حتما استفاده خواهد شد را توضیح دهیم. در اینجا ما در ارتباط با فایل های WSDL و اینکه چطور می توان از آنها استفاده کرد بحث خواهیم کرد همچنین به شما نشان می دهیم که به چه صورت می توان فایل WSDL  را با NuSOAP ایجاد کنید و آن را با مثال های سرور و کلاینت SOAP که در قسمت قبل ایجاد کردیم ترکیب کنیم. در ادامه مطلب همراه من باشید. چیست و چه کاربردی دارد؟

دانلودها

  • آموزش لاراول: معرفی و آموزش گام به گام Laravel
  • آموزش ساخت بازی XO با استفاده از React - بخش دوم
  • آموزش ساخت بازی XO با استفاده از React - بخش اول
  • آموزش React - قسمت سوم
  • آموزش React - قسمت دوم

سوالات

  • اضافه کردن یک ستون جدید به جدول موجود در Migration لاراول

    چطور می توانم یک ستون به جدولی که از قبل با استفاده از فریموورک لاراول ایجاد شده است اضافه کنم؟من فایل Migration رو به صورت زیر ویرایش کردم:<?php public function up() { Schema::create('users', function ($table) { $table->integer("paid"); }); }در ترمینال هم دستور php artisan migrate:install  و migrate رو اجرا کردم، اما ستون اضافه نشده است.چطور می توانم ستون مورد نظرم را اضافه کنم؟
  • چک کردن موجود بودن یک رکورد در Laravel

    من تازه کار با فریممورک Laravel رو شروع کردم. چطور می توانم بررسی کنم که یک رکورد موجود است یا خیر؟$user = User::where('email', '=', Input::get('email'));چطور می می تونم بررسی کنم که user$ شامل رکورد هست یا نه؟
  • لاراول 4: چطور می توان در Blade آدرس صفحه را دریافت کرد؟

    من از لاراول نسخه 4 استفاده می کنم، چطور می توانم آدرس یک صفحه را دریافت کنم و در if@ استفاده کنم. می دونم که  می توانم با استفاده از کد PHP زیر این کار را انجام دهم:<?php echo URL::current(); ?>اما در blade چطور می توان این کار را انجام داد؟
  • چطور می توان چندین شرط Where در Eloquent لاراول در نظر گرفت؟

    من از Query Builder لاراول برای ایجاد گزارش استفاده می کنم و گزارشم دارای چندین شرط می باشد.شرط ها را به صورت زیر اعمال کردم اما به نظرم راه جالبی نیست.$results = User::where('this', '=', 1) ->where('that', '=', 1) ->where('this_too', '=', 1) ->where('that_too', '=', 1) ->where('this_as_well', '=', 1) ->where('that_as_well', '=', 1) ->where('this_one_too', '=', 1) ->where('that_one_too', '=', 1) ->where('this_one_as_well', '=', 1) ->where('that_one_as_well', '=', 1) ->get();آیا راه بهتری برای اعمال شرط ها وجود دارد؟
  • چطور می توان گزارش SQL که Query Builder لاراول آن را ایجاد می کند مشاهده کرد؟

    کد زیر را در نظر بگیرید:DB::table('users')->get();من می خوام کد SQL که Query Builder بالا اجرا می کند را دریافت کنم به عنوان مثال در کد بالا کد SQL:SELECT * FROM usersتوسط Query builder اجرا می شود.
  • Eloquent: شمارش و تشخیص خالی بودن

    آیا راهی برای تشخیص اینکه مجموعه بازگشتی از گزارش:$result = Model::where(...)->get() خالی است یا اینکه تعداد عناصر موجود در آن چقدر است وجود دارد؟من در حال حاضر از:!$result استفاده می کنم آیا راه درستی است؟در مورد:count($result)آیا همه موارد را پوشش می دهد؟ به عنوان مثال اگر result خالی باشد؟
  • لاراول 5: نمایش HTML در Blade

    من یک رشته به صورت زیر دارم که شامل تگ HTML می باشد:$text = '<p><strong>Lorem</strong> ipsum dolor <img src="images/test.jpg"></p>'و می خواهم با استفاده از Blade نمایش بدم:{{$text}}اما خود رشته را چاپ می کند و تگ های HTML را رندر نمی کند. چطور می توانم HTML را با Blade در لاراول 5 نمایش بدم؟
  • ReactJSX: استفاده از Props بین کوتیشن

    چطور می توان در JSX از یک مقدار props به عنوان مقدار attribute استفاده کرد؟به عنوان مثال:<img className="image" src="images/{this.props.image}" />و خروجی HTML آن به صورت زیر است:<img class="image" src="images/{this.props.image}"> 
  • ارتباط بین دو کامپوننت در React

    اپلیکیشن من شامل یک لیست با فیلتر های آن و یک button برای تغییر layout می باشد. در حال حاضر از سه کامپوننت:</list></Filters></TopBar>استفاده می کنم. می خوام زمانی که تنظیمات در </Filters> تغییر کرد متدی در کامپوننت </list> برای بروزرسانی view اجرا شود.چطور میتونم بین این سه کامپوننت ارتباط برقرار کنم؟ آیا باید از مدل داده global برای انجام این کار استفاده کنم؟ 
  • Show یا Hide کردن عنصر در React

    من تازه شروع به یادگیری React کردم و دنبال راهی هستم که بتونم یک عنصر روی صفحه را show یا hide کنم.  می خوام زمانی که کلیک کردم، div مربوط به نتایج نمایش داده شود.var Search= React.createClass({ handleClick: function (event) { console.log(this.prop); }, render: function () { return ( <div className="date-range"> <input type="submit" value="Search" onClick={this.handleClick} /> </div> ); } }); var Results = React.createClass({ render: function () { return ( <div id="results" className="search-results"> Some Results </div> ); } }); React.renderComponent(<Search /> , document.body); 

اشتراک

منو
خانه
ویدئو
دانلود
اپلیکیشن
درباره ما
خدمات
قالب سایت
خدمات
ما را دنبال کنید
Android Logo
Github Logo
© 2015 - 2023 All rights reserved