نمایش داده های خارجی در ری اکت

24 فروردین 1398
درسنامه درس 16 از سری آموزش react (ری اکت)
React-display-api-data

تا به اینجای آموزش ما با promise ها کار کردیم، برنامه مان را توسط npm ایجاد و کتابخانه whatwg-fetch را برای واکشی آبجکت های از راه دور نصب کردیم و در این درس می خواهیم داده های خارجی را وارد برنامه مان کنیم.

واکشی داده ها (Fetch Data)

به منظور سادگی کار، در این درس فقط از آن قسمتی که زمان جاری را از یک سرور از راه دور دریافت می کردیم، کار می کنیم.

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

ابتدا کامپوننت مورد نظر را ایجاد کرده و زمان جاری را مانند زیر واکشی می کنیم. کدهای زیر را کپی کرده و در داخل فایل src/App.js قرار دهید.

import React from 'react';
import 'whatwg-fetch';
import './App.css';
import TimeForm from './TimeForm';

class App extends React.Component {
  constructor(props) {
    super(props);

    this.fetchCurrentTime = this.fetchCurrentTime.bind(this);
    this.handleFormSubmit = this.handleFormSubmit.bind(this);
    this.handleChange = this.handleChange.bind(this);

    this.state = {
      currentTime: null, msg: 'now'
    }
  }

  // methods we'll fill in shortly
  fetchCurrentTime() {}
  getApiUrl() {}
  handleFormSubmit(evt) {}
  handleChange(newState) {}

  render() {
    const {currentTime, tz} = this.state;
    const apiUrl = this.getApiUrl();

    return (
      <div>
        {!currentTime &&
          <button onClick={this.fetchCurrentTime}>
            Get the current time
          </button>}
        {currentTime && <div>The current time is: {currentTime}</div>}
        <TimeForm
          onFormSubmit={this.handleFormSubmit}
          onFormChange={this.handleChange}
          tz={tz}
          msg={'now'}
        />
        <p>We'll be making a request from: <code>{apiUrl}</code></p>
      </div>
    )
  }
}

export default App;

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

حال توسط create-react-app کامپوننت TimeForm را ایجاد می کنیم. فایل src/TimeForm.js را به پروژه تان اضافه کنید.

touch src/TimeForm.js

حال بدنه متد را اضافه می کنیم. ما می خواهیم به کاربران این امکان را بدهیم تا بتوانند بین timezoneهای مرورگرشان سوئیچ کنند. اینکار را با ایجاد یک کامپوننت stateful به نام TimeForm انجام می دهیم. کدهای کامپوننت TimeForm مطابق زیر است:

import React from 'react'
const timezones = ['PST', 'MST', 'MDT', 'EST', 'UTC']

export class TimeForm extends React.Component {
  constructor(props) {
    super(props);

    this.fetchCurrentTime = this.fetchCurrentTime.bind(this);
    this.handleFormSubmit = this.handleFormSubmit.bind(this);
    this.handleChange = this.handleChange.bind(this);

    const {tz, msg} = this.props;
    this.state = {tz, msg};
  }

  _handleChange(evt) {
    typeof this.props.onFormChange === 'function' &&
      this.props.onFormChange(this.state);
  }

  _changeTimezone(evt) {
    const tz = evt.target.value;
    this.setState({tz}, this._handleChange);
  }

  _changeMsg(evt) {
    const msg =
      encodeURIComponent(evt.target.value).replace(/%20/, '+');
    this.setState({msg}, this._handleChange);
  }

  _handleFormSubmit(evt) {
    evt.preventDefault();
    typeof this.props.onFormSubmit === 'function' &&
      this.props.onFormSubmit(this.state);
  }

  render() {
    const {tz} = this.state;

    return (
      <form onSubmit={this._handleFormSubmit}>
        <select
          onChange={this._changeTimezone}
          defaultValue={tz}>
          {timezones.map(t => {
            return (<option key={t} value={t}>{t}</option>)
          })}
        </select>
        <input
          type="text"
          placeholder="A chronic string message (such as 7 hours from now)"
          onChange={this._changeMsg}
        />
        <input
          type="submit"
          value="Update request"
        />
      </form>
    )
  }
}

export default TimeForm;

بعد از ایجاد کامپوننت با دستور npm start آن را اجرا کرده و می بینیم که فرم مان ساخته و در مرورگر نمایش داده می شود، البته تا به اینجا هنوز قابلیت واکشی داده ها را اضافه نکردیم، که در مرحله بعد این کار را انجام می دهیم.

دریافت و نمایش داده ها

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

حال درخواست مان را در قالب یک URL به سرور ارسال کرده تا سرور زمان جاری را به ما برگرداند.

من قبلاً یک متد به نام ()getApiUrl در کامپوننت App ایجاد کرده بودم. حال می خواهم کدهای این تابع را تکمیل کنم. سرور API یک سری متغیر را دریافت می کند، که ما توسط آنها فرم مان را سفارشی می کنیم.

همچنین یک timezone به همراه یک پیام را از سرور chronic دریافت می کنیم. ما از کتابخانه chonic ، محدوده زمانی (timezone (pst را به همراه زمان جاری (now) درخواست می کنیم.

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      currentTime: null, msg: 'now', tz: 'PST'
    }
  }
  // ...
  getApiUrl() {
    const {tz, msg} = this.state;
    const host = 'https://andthetimeis.com';
    return host + '/' + tz + '/' + msg + '.json';
  }
  // ...
export default App;

حال هنگامی که ()getApiUrl را فراخوانی می کنیم، URL درخواست بعدی، برای ما برگشت داده می شود.

حال می خواهیم متد fetch() را پیاده کنیم. متد ()fetch چند آرگومان را گرفته و به ما کمک می کند تا درخواست مان را سفارشی کنیم. درخواست get در ساده ترین حالت خود، تنها یک  آدرس URL را می گیرد. مقدار برگشتی تابع ()fetch یک promise است، که در درس قبلی به طور مفصل راجع به آن صحبت کردیم.

حال متد fetchCurrentTime() را به منظور دریافت زمان جاری از یک سرور از راه دور، بروزرسانی میکنیم. با فراخوانی متد ()json بر روی آبجکت Response، محتوای response ارسال شده از سرور را از یک آبجکت json به آبجکت جاوا اسکریپت تبدیل کرده و سپس کامپوننت مان را با قراردادن مقدار response برابر dateString، به عنوان زمان جاری در state کامپوننت، بروزرسانی می کنیم.

class App extends React.Component {
  // ...
  fetchCurrentTime() {
    fetch(this.getApiUrl())
      .then(resp => resp.json())
      .then(resp => {
        const currentTime = resp.dateString;
        this.setState({currentTime})
      })
  }
  // ...
}

در قسمت آخر پروژه، داده های فرم را گرفته و کامپوننت والد را بروزرسانی می کنیم. با اینکار، هنگامی که کاربر مقادیر را از کامپوننت TimeForm بروزرسانی کند، باید بتوانیم به این داده ها از داخل کامپوننت App دسترسی داشته باشیم.

کامپوننت TimeForm قبلاً این پروسه را برای مان مدیریت می کرده، بنابراین تنها باید توابع فرم مان را پیاده سازی کنیم.

هنگامی که یک بخش از state روی کامپوننت فرم تغییر کند، یک پروپرتی به نام oFormChange فراخوانی می شود. با تعریف این متد در داخل کامپوننت App ، می توانیم به آخرین نسخه فرم دسترسی داشته باشیم.

در حقیقت، با فراخوانی متد ()setState، تغییراتی که کاربر اجازه دارد تا روی فرم اعمال کند را کنترل می کنیم.

class App extends React.Component {

// ...
  handleChange(newState) {
    this.setState(newState);
  }

// ...
}

در انتها، هنگامی که کاربر فرم را submit کرد (با کلیک روی دکمه فرم یا فشردن دکمه Enter)، یک درخواست دیگر برای دریافت زمان، ارسال می کنیم.

برای اینکار یک پروپرتی به نام handleFormSubmit برای فراخوانی متد ()fetchCurrentTime تعریف می کنیم.

class App extends React.Component {

// ...
  handleFormSubmit(evt) {
    this.fetchCurrentTime();
  }

// ...
}

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

در درس بعدی، چندین صفحه را به پروژه مان اضافه کرده و داده ها را در آن صفحات نمایش می دهیم.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش react (ری اکت) توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.