کار با React Js

سه شنبه 2 خرداد 1396

کتابخانه ها و چارچوب هایی (frameworks) مانند React js به سرعت در حال پیشرفت هستند. به این خاطر که قابلیت های این چارچوب ها فراهم کرده اند، زبان جاوا اسکریپت این روزها از اهمیت و توجه زیادی برخوردار شده است. یکی از محبوب ترین کتابخانه هایی که مشکلات مربوط با View را حل کرده است، React Js از Facebook است. در این مقاله مقدمات آموزشی از این کتابخانه به همراه چند مثال کوچک در اختیارتان قرار داده شده است.

 کار با React Js

کتابخانه ها و چارچوب هایی (frameworks) مانند React js  به سرعت در حال پیشرفت هستند. به این خاطر که قابلیت های این چارچوب ها فراهم کرده اند، زبان جاوا اسکریپت این روزها از اهمیت و توجه زیادی برخوردار شده است.

یکی از محبوب ترین کتابخانه هایی که مشکلات مربوط با View را حل کرده است، React Js از Facebook است. در این مقاله مقدمات آموزشی از این کتابخانه به همراه چند مثال کوچک در اختیارتان قرار داده شده است.

چرا React js؟

Facebook کتابخانه React را ساخت برای رسیدگی به چالش قدیمی به شکلی مؤثر برای مقابله با بخش View  در معماری های MVC که همان Model-View-Controller هستند.

Reac js اهمیت گران قیمت ویرایش Dom را درک کرد، بنابراین یک DOM مجازی برای توسعه دهنده به وجود آورد. هر زمان که تغیری در قسمت رابط کاربری ایجاد شدو، React js محاسبه می کند تعداد کوچکی از عملیات DOM را که نیاز است برای حالت جدید به دست بیاورد. این به شما اجازه می دهد تا صفحه را برای هر تغییر کوچکی بدون نگرانی از بهینه بودن یا نبودن DOM یا DOM Performance نمایش دهید.

React  یک روش اعلانی را برای ساخت رابط کاربری سفارشی بصورت کامپوننت فراهم کرده است که آن را در صفحه نمایش دهد. به این رویکرد روش بالا به پایین (top-down) می گویند، به این معنا که داده همیشه در بالا و پایین عناصر قرار می گیرد.

استفاده از این کتابخانه بسیار آسان است.

اگر یک جستجو کوچک درباره رشد زبان جاوا اسکریپت و رشد کتابخانه ها و چارچوب هایش کنید، متوجه رشد چشم گیر آن ها خواهید شد:

نکته: به خاطر داشته باشید که React تنها برای کار با رابط کاربری است. یک چارچوب کامل مانند انگولار نیست که کار با رابط کاربری، داده، مقید سازی (Binding)، مسیریابی (Routing)، کار با HTTP را انجام دهد. برای مدیریت داده شناور و داده در اپلیکیشن های React، شرکت بزرگ Facebook، کتابخانه های Flux و Redux را آفریده است.

هم Flux و هم  Redux از الگو های برنامه های React پشتیبانی می کند. در اینجا کتابخانه کمکی یا Third Party Library یا همان پلاگین های react قابلیت های دیگری مانند Routing را اضافه می کنند. برای ساختن یک SPA کامل توسط React، ما نیاز داریم تا کتابخانه های مختلف را با هم استفاده کنیم. که البته بحث در این باره خارج از محدوده این مقاله است.

React.js – مفاهیم بنیادی و مقدماتی

قبل از اینکه یک برنامه React js بسازید، مقداری از زمانتان را برای در ک مفاهیمی که با React درگیر است کنید.

Virtual DOM

همه از قدرت DOM که وظیفه ساخت و مدیریت در HTML داخل مرورگرها دارد، آگاه هستید. React یک DOM دیگر به نام Virtual DOM برای کار با برنامه ها ساخته است.

Virtual DOM هر زمان که داده در کامپوننت ویرایش شود، به روز رسانی می شود. بعد از به روزرسانی Virtual DOM، کتابخانه React تفاوت میان حالت جدید و حالت قبل را بررسی می کند نه کل رابط کاربری را. این عملیات باعث می شود که برنامه های React با سرعت بیشتری اجرا شوند و بهینه تر باشند، بنابراین React فقط بخش هایی که از UI به روز رسانی می شود را تغییر می دهد.

Components

کامپوننت ها عناصر سفارشی HTML هستند اما با رفتاری مشخص کارشان را انجام می دهند. در React همیشه کامپوننت ها در یک کلاس کامپوننت ساخته می شود. یک کامپوننت یک متد نمایش دارد (render method)، که یک View بر می گرداند زمانیکه کامپوننت در صفحه استفاده می شود. کاپوننت ها همچنین داده را مدیریت می کنند برای مقید سازی (binding) داده در View.

یک کامپوننت در React می تواند ساخته شود با استفاده از متد React.createClass یا به عنوان کلاس جاوا اسکریپت با گسترش دادن کلاس کامپوننت  در React. تکه کد پایین به شما یک کامپوننت بسیار ساده را نمایش می دهد.

var First = React.createClass({
  render(){
    return <div>This is my first component!</div>;
  }
});

JSX

JSX اضافه کننده XML به جاوا اسکریپت است.

View ها در کامپوننت های React توسط JSX تعریف می شوند. عناصر HTML و دیگر کامپوننت های React در داخل یک کامپوننت با استفاده JSX نمایش اشاره می شوند که به شما اجازه می دهد داده را مقید سازید بر روی عناصر HTML، مدیریت روی داده با استفاده از متد هایی که بر روی کامپوننت موجود است و مقادیر را بر روی عناصر HTML مقید سازید.

هر کامپوننت در React برای پیاده سازی متد render نامیده می شود، این متد مجبور است تا به JSX برگردانده شود برای نمایش در یک View.

مثال زده شده به شما نحوه کاکرد JSX را به خوبی نشان می دهد. در آینده مثال های بیشتری خواهید دید.

چرخه زندگی متدهای کامپوننت React.js

React برای ما چرخه ای فراهم می کند تا متدها اجرا شوند تا یک قطعه کد منطقی را زمانیکه این رویداد ها رخ می دهد، اجرا کند.

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

متد های چرخه زندگی React بصورت زیر آمده است

componentWillMount: زمانیکه کامپوننت بر روی صفحه سوار است، این متد فراخوانی می شود

componentDidMount: زمانیکه کامپوننت بر روی صفحه نمایش داده می شود، این متد فراخوانی می شود.

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

componentWillRecieveProps: زمانیکه کامپوننت خواصی دریافت می کند یا زمانی که خواص به روز رسانی می شوند، این متد فراخوانی می شود

componentDidUpdate: به سرعت بعد از ویرایش فراخوانی می شود به این خاطر که داده در کامپوننت به روز رسانی شود

componentWillUnmount: قبل از اینکه یک کامپوننت از DOM حذف شود فراخوانی می شود. برای اینکه بتواندهر وظیفه ای را در کامپوننت بصورت کامل انجام دهد، استفاده می شود.

State, Props and Unidirectional data flow

هر کامپوننت یک حالتی از شئ دارد که نقش View Model را برای کامپوننت بازی می کند. React  بر روی داده های immutable کار می کند، بنابراین حالت شئ بازسازی می شود هرزمان که تغییری در مقدار آن به وجود آید. متد های چرخه زندگی componentWillUpdate و componentDidUpdate فراخوانی می شوند.

 یک کامپوننت می تواند ورودی ها را از کامپوننت دیگر از طریق ویژگی های عناصر دریافت کند. آن ها Props صدا زده می شوند. چرخه زندگی componentWillRecieveProps زمانی فراخوانی می شود که خواص تنظیم یا ویرایش شوند. مقادیری از خواص که از کامپوننت عبور داده می شوند شامل کامپوننت کنونی است، مقادیر از prop ها می تواند ویرایش شود البته فقط در کامپوننت پدر. زمانیکه مقادیر تغییر می کنند،  متد چرخه زندگی componentWillRecieveProps فرزند را اجرا می کند.

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

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

ساخت یک برنامه سلام جهان در Codepen

تاکنون با مفاهیم اصلی React آشنا شدید، حالا وقت آن رسیده تا از این مفاهیم خوانده شده در قالب یک مثال استفاده کنید. مانند هر تکنولوژی دیگر Front-End، برای توسعه React نیاز به محیطی دارید که node.js در آن نصب شده باشد.

شما می توانید Node.js را از سایت رسمی آن دانلود کنید، اگر هم اکنون بر روی سیستم شما نصب نیست. فایل نصب کننده Nodejs هم خود Nodejs و هم مدیریت بسته ای (package manager) به نام NPM را نصب می کند. یک برنامه React می تواند با هر نسخه ای از جاوااسکریپت نوشته شود حتی با استفاده از پیش پردازنده های جاوا اسکریپتی مانند TypeScript.

نکته: علاوه بر NPM یک مدیریت بسته دیگری برای بسته های جاوا اسکریپتی وجود دارد، به نام yarn. Yarn توسط Facebook ساخته شده است که بیشتر قابلیت های NPM را برای توسعه دهندگان دارد.

Yran یک مدیریت بسته بسیار سریع، ایمن، قابل اعتماد است. این مدیریت بسته یک مخزن بسته جدید ندارد و آن با NPM کار می کند و کمک می کند تا نسخه های جدیدی از بسته ها را نگهداری کند. امروزه محبوبیت بسیاری به خاطر ویژگی هایش پیدا کرده است. برای یادگیری Yarn می توانید به سایت رسمی https://yarnpkg.com/en/ مراجعه کنید.

سایت http://codepen.io را باز کنید و به مرورگر علاقه مندی های خود اضافه کنید. بر روی Pen button در بالا سمت راست کلیک کنید و یک دمو جدید بسازید.

برای نوشتن یک برنامه React، نیاز است تا چند ویژگی را به آن اضافه کنیم.

بر روی کلید تنظیمات (Setting) در بالا سمت راست صفحه کلیک کنید سپس به تب javascript بروید.

در اینجا Transpiler رو تنظیم کنید و کتابخانه های مورد نیاز React را اضافه نمایید. تنظیمات در پایین به شما نمایش داده شده است:

اکنون بر روی ذخیره کلیک کنید و پنجره را ببندید.

در حال حاضر شما منابع ساخت برنامه React را دارید. ابتدا یک برنامه ساده سلام دنیا می نویسیم.

    var Hello = React.createClass({
        render: function () {
            return (
                <div>This is my first react component!</div>
            );
        }
    });

در مثال بالا با استفاده از نسخه ES5 برای نوشتن کامپوننت استفاده کردیم. همانطور که مشاهده می کنید، برای ساختن کامپوننت از کلاس createClass استفاده شده است. تابع render در شیئ کامپوننت یک شیئ JSX باز می گرداند تا داخل کامپوننت نمایش داده شود.

به زودی مثال های بیشتری از JSX زده می شود.

اکنون این کامپوننت در صفحه نمایش داده می شود. زمانیکه شما این خط کد را در زیر کد بالا اضافه نمایید.

    ReactDOM.render(<Hello/>, document.getElementById('root'));

خوب دقت کنید که در پارامتر اول کامپوننت پاس داده شده است. پارامتر دوم هدف ما در DOM گرفته است؛ درواقع جایی که باید کامپوننت نمایش داده شود.

در اینجا div انتخاب شده است و در قالب نمایش داده می شود.

خروجی کد پن:

در واقع در مثال قبل، پیام نمایش داده شده در کامپوننت به اصطلاح hard code شده است در عنصر div. زمان آن رسیده تا کد خود را refactor کنید.

var Hello = React.createClass({
  getInitialState: function(){
    return { message: "This is my first react component!" };
  },
  render: function(){
    return (
      <div>{this.state.message}</div>
    );
  }
});

کامپوننت یک متد جدید به نام getInitialState گرفته است. این متد یک حالت شیئ را از کامپوننت باز می گرداند. حالت شیئ می تواند برای مقید سازی (bind) داده و رویداد برای نمایش کامپوننت استفاده شود. خروجی این کد نیز مانند قبل است.

اکنون تصمیم بر این است که بعد از 5 ثانیه این پیام چاپ شود:

همانطور که قبلا هم اشاره شد، حالت شیئ (state object) از نوع immutable است و هر تغییری در این شیئ یک حالت جدیدی از شیئ را می سازد. React برایتان یک متد به نام setState بر روی هر کامپوننت فراهم کرده است و این بهتر است تا یک timeout تعریف شود برای تغییر پیام زمانی که کامپوننت اجرا شده است. برای اینکار نیاز است تا از چرخه زندگی componentDidMount استفاده کنید.

componentDidMount: function(){
  setTimeout(() => {
    this.setState({ message: "This message is modified after 5 seconds!" });
  }, 5000);
} 

همانطور که مشاهده می کنید، پیامتان بعد از 5 ثانیه تغییر می کند.

یک مثال قوی تر از React

سیستم راه اندازی یک محیط توسعه برای React نیاز به زمان و تلاش دارد. برای صرفه جویی در زمان راه اندازی، ما باید بسته NPM را ایجاد کنیم و پکیج create-react-app را نصب کنیم.

> npm install –g create-react-app

درصورتیکه با موفقیت کد بالا نصب شود، توانایی ایجاد یک پروژه جدید Reactjs را به وسیله اجرا کردن دستور پایین در بخش دستورات سیستم عامل (commandline, bash, …) می توانید پروژه تان برا شروع کنید:

> create-react-app my-app

این دستور پوشه جدیدی به نام my-app می سازد و چند فایل و پوشه به آن اضافه می کند. همچنین همه وابستگی های مورد نیاز پروژه را تأمین می کند.

با اینکار می توانید شما بصورت مستقیم بدون هیچ نگرانی پروژه تان را آغاز کنید. البته پروژه ساخته شده چند کد کوچک نیز برای اجرا گرفتن و تست پروژه برای شما زده است. تصویر زیر چیدمان پوشه برنامه ساخته شده در ویژوال استادیو کد را نمایش می دهد.

برنامه تولید شده مقداری کد react دارد. یک کامپوننت به نام app دارد و این کامپوننت در صفحه index.html نشان داده می شود.

برای آغاز این اپلیکیشن دستور زیر را در commandprompt بزنید:

> npm start

این دستور برنامه را در مرورگر پیش فرضتان اجرا می کند. می توانید تصویر آن را در زیر مشاهده کنید:

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

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

کد کامپوننت بصورت زیر است:

import React, { Component } from 'react';
export class ListView extends Component {
  constructor(props) {
    super(props);
    this.state = {
      employees: [
        {
          name: "Alex Kesler",
          designation: "Software Architect",
          project: "URR"
        },
        {
          name: "Raghu Shah",
          designation: "Software Engineer",
          project: "SHU"
        },
        {
          name: "Kim Lee",
          designation: "Intern",
          project: "URR"
        },
        {
          name: "Joe Walsh",
          designation: "Manager",
          project: "SHU"
        },
        {
          name: "Christine Sam",
          designation: "QA Engineer",
          project: "FHD"
        },
        {
          name: "Tim Asermeley",
          designation: "UX Designer",
          project: "FHD"
        },
        {
          name: "Raji Sinha",
          designation: "Tech Lead",
          project: "SHU"
        }
      ]
    };
  }
  render() {
    let jsx = <table style={{ display: "inline-table" }}>
      <thead>
        <tr>
          <th>Name</th>
          <th>Designation</th>
          <th>Project</th>
        </tr>
      </thead>
      <tbody>
        {
          this.state.employees.map(function (employee) {
            return <tr key={employee.name}>
              <td>{employee.name}</td>
              <td>{employee.designation}</td>
              <td>{employee.project}</td>
            </tr>
          })
        }
      </tbody>
    </table>;
 
    return jsx;
  }
}

این کامپوننت متفاوت از کامپوننتی است که در ابتدای مقاله نوشته شد.

دقت کنید که از نسخه ES2015 در این کد استفاده شده است. کلاسی ساختیم برای کامپوننت به جای اینکه متد    React.createClass را بر روی React object صدا بزنیم.

برای تنظیم حالت شئ (state object) در کلاس، نیازی نیست تا متد getInitialState  را به عنوان  سازنده کلاس(constructor) برای آغاز کردن حالت شئ (initialize state) بنابراین  تمامی تنظیمات حالت شئ را بصورت مستقیم در سازنده کلاس معرفی می کنیم.

یک بار دیگر لطفا به این نکته توجه کنید که در سازنده نام برده شده، سازنده کلاس  super() صدا زده می شود. با این کار خواص کامپوننت کنونی پاس داده می شود.

بعضی ها ممکن است این سوال برایشان پیش بیاید که چطور از ترکیب جاوااسکریپت و XML در ویژوال استادیو کد می توان استفاده کرد. با تشکر از ویرایشگر، یک پشتیبانی خیلی خوب از قواعد JSX می کند. آن همچنین از emmet، zen coding of HTML در داخل بلاک های JSX نیز پشتیبانی می کند

یک نگاه نزدیک تر به JSX کامپوننت نوشته شده کنید. یک جدول دارد که میان داده کارمندان پیمایش می کند و هر سطر را بر روی صفحه نمایش چاپ می کند.

کد زیر عنصر table را نمایش می دهد:

<table style={{ display: "inline-table" }}>

برای حلقه ای که در آرایه کارمندان پیمایش می کند، ما یک متد map نوشتیم از آرایه ای که در JSX قرار دارد و متد map سطری که برای هر رکورد چاپ می کند را می سازد.

قطعه کد زیر نشانگر حلقه ای است که در لیست کارمندان پیمایش می شود:

this.state.employees.map(function (employee) {
  return <tr key={employee.name}>
    <td>{employee.name}</td>
    <td>{employee.designation}</td>
    <td>{employee.project}</td>
  </tr>
})

اگر شما قبلا با Jquery کار کرده بودید، این حلقه خیلی شبیه به روشی است که بصورت دستی در markup حلقه می نوشتید.

برای استفاده از این کامپوننت در کامپوننت App نیاز است که کامپوننت جدیدمان را در داخل آن اضافه کنیم.

کد ان بصورت زیر است:

import React, { Component } from 'react';
import { ListView } from './ListView';
import logo from './logo.svg';
import './App.css';
class App extends Component {
  render() {
    let jsx = <div>
      <div>
        <img src="{logo}" alt="logo" />
        <h2>A list of Employees</h2>
      </div>
      <ListView />
    </div>;
    return (
      jsx
    );
  }
}
export default App;

اکنون صفحه به شکل زیر است:

حالا یک کامپوننت دیگر برای کنترل فیلتر های داده و ارتباط با داده در یک کامپوننت به نام ListView استفاده می کنیم.

کد آن مانند زیر است.

import React, { Component } from 'react';
import { ListView } from './ListView';
export class Filter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      field: "name",
      value: ""
    };
    this.filter = this.filter.bind(this);
    this.setField = this.setField.bind(this);
  }
  render() {
    let jsx = <div>
      <div>Field: 
        Name
        Designation
        Project
      </div>
      <div>Value: </div>
      <ListView field={this.state.field} value={this.state.value} />
    </div>;
    return (
      jsx
    );
  }
  setField(event) {
    this.setState({ field: event.target.value });
  }
  filter(event) {
    this.setState({ value: event.target.value });
  }
}

این کد از یک drop-down استفاده می کند تا فیلدی که قرار است فیلتر شود را مشخص کند. آن همچنین یک Textbox دارد برای گرفتن مقادیری که در فیلتر استفاده می شوند. دقت کنید که منو کشویی یا همان drop-down و text-box یک رویداد به نام onChange دارند که در متد های کلاس کامپوننت قرار می گیرند.

this.filter = this.filter.bind(this);
this.setField = this.setField.bind(this);

این کار انجام شده برای اطمینان خاطر آن است که بگوید this به کامپوننت کنونی در داخل متد های مدیریت رویداد handling event اشاره می کند. در غیر اینصورت متد های مدیریت رویداد در یک زمینه global صدا زده می شوند که ما نمی خواهیم به اعضای داخل کلاس کامپوننت دسترسی داشته باشیم.

JSX از کامپوننت فیلتر از کامپوننت ListView استفاده می کند و مقادیر را از state.field و state.value به کامپوننت ListView پاس می دهد. این مقادیر در داخل کامپوننت ListView از طریق props قابل دسترس است. زمانیکه مقادیر ویرایش می شوند، React متد render را البته از کامپوننت ListView را صدا می زند.

بنابراین، ما نیاز داریم این مقادیر در متد render برای فیلتر داده و کامپوننت JSX را می سازد.

کد زیر نمایان گر کد ویرایش شده متد render در کامپوننت ListView و یک متد فیلتر داده است:

filterEmployees() {
  let employees = this.state.employees;
  if (this.props.field && this.props.value) {
    employees = this.state.employees.filter((e) => {
      return e[this.props.field].toLowerCase().indexOf(this.props.value.toLowerCase()) >= 0;
    });
  }
  return employees;
}
 
render() {
  let employees = this.filterEmployees();
  let jsx = <table style={{ display: "inline-table" }}>
    <thead>
      <tr>
        <th>Name</th>
        <th>Designation</th>
        <th>Project</th>
      </tr>
    </thead>
    <tbody>
      {
        employees.map(function (employee) {
          return <tr key={employee.name}>
            <td>{employee.name}</td>
            <td>{employee.designation}</td>
            <td>{employee.project}</td>
          </tr>
        })
      }
    </tbody>
  </table>;
  return jsx;
}

اکنون تمام چیزی که نیاز داریم این است که کامپوننت App را برای استفاده از کامپوننت Filter ویرایش کنیم.

قطعه کد زیر نشانگر کد ویرایش شده کامپوننت App است:

import React, { Component } from 'react';
import { Filter } from './Filter';
import logo from './logo.svg';
import './App.css';
 
class App extends Component {
  render() {
    let jsx = <div>
      <div>
        <img src="{logo}" alt="logo" />
        <h2>A list of Employees</h2>
      </div>
      <Filter />
    </div>;
    return (
      jsx
    );
  }
}
export default App;

در عکس زیر شما مشاهده می کنید که جدول به روزرسانی می شود هربار که شما نوع فیلتر را تغییر می دهید.

نتیجه گیری

امروزه برنامه نویسان از مدلی براساس کامپوننت استفاده می کنند. React.js یک کتابخانه ای است که از این مدل برای توسعه پشتیبانی می کند. این مقدمه ای بر آموزش Reactjs بود امیدوارم که مورد پسندتان قرار گرفته باشد.

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید