تا به اینجای آموزش ما با promise ها کار کردیم، برنامه مان را توسط npm ایجاد و کتابخانه whatwg-fetch را برای واکشی آبجکت های از راه دور نصب کردیم و در این درس می خواهیم داده های خارجی را وارد برنامه مان کنیم.
به منظور سادگی کار، در این درس فقط از آن قسمتی که زمان جاری را از یک سرور از راه دور دریافت می کردیم، کار می کنیم.
این کامپوننت ری اکت یک درخواست به سرور ارسال کرده و زمان جاری را از ساعت سرور دریافت و به ما بر می گرداند. قبل از اینکه واکشی را انجام دهیم، باید چند کامپوننت 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(); } // ... }
در این درس، بر روی دریافت داده ها از یک سرورخارجی و نمایش آنها در یک برنامه ری اکت، تمرکز کردیم. اما در این جا، ما تنها از یک صفحه در برنامه مان استفاده کردیم. اگر بخواهیم در چند صفحه آنها را نمایش دهیم، باید چکار کنیم؟
در درس بعدی، چندین صفحه را به پروژه مان اضافه کرده و داده ها را در آن صفحات نمایش می دهیم.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.