• No results found

Walls of code warning

In document 30 Days of React eBook Fullstackio (Page 150-159)

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;

The p e ious component is a basic stateful React component as e' e

c eated. Since e'll ant to sho a fo m, e' e included the intended usage of the TimeForm let's c eate ne t.

Let's c eate this component in ou eact app using create-react-app. Add

the file src/TimeForm.js into ou p oject:

touch src/TimeForm.js

No let's add content. We'll ant ou TimeForm to take the ole of allo ing

the use to s itch bet een timezones in thei b o se . We can handle this b c eating a stateful component e'll call the TimeForm. Ou 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 (

<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;

With these Components c eated, let's load up ou app in the b o se afte unning it ith npm start and e'll see ou fo m albeit not inc edibl

beautiful et . Of cou se, at this point, e on't ha e a unning component as e ha en't implemented ou data fetching. Let's get to that no .

As e said este da , e'll use the fetch() API ith p omise suppo t. When

e call the fetch() method, it ill etu n us a p omise, he e e can handle

the e uest ho e e e ant. We' e going to make a e uest to ou no - based API se e so sta t-up might be slo if it hasn't been un in a hile . We' e going to be building up the URL e'll e uest as it ep esents the time

ue e'll e uest on the se e .

I' e al ead defined the method getApiUrl() in the App component, so let's

fill that function in.

The ch onic api se e accepts a fe a iables that e'll customize in the fo m. It ill take the timezone to along ith a ch onic message. We'll sta t simpl and ask the ch onic lib a fo the pst timezone and the cu ent time

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;

No , hen e call getApiUrl(), the URL of the ne t e uest ill be etu ned

fo us. No , finall , let's implement ou fetch() function. The fetch()

function accepts a fe a guments that can help us customize ou e uests. The most basic GET e uest can just take a single URL endpoint. The etu n

Let's update ou fetchCurrentTime() method to fetch the cu ent time f om

the emote se e . We'll use the .json() method on the esponse object to

tu n the bod of the esponse f om a JSON object into Ja aSc ipt object and then update ou component b setting the esponse alue of the dateString

as the currentTime in the component state:

class App extends React.Component { // ...

fetchCurrentTime() { fetch(this.getApiUrl()) .then(resp => resp.json()) .then(resp => {

const currentTime = resp.dateString; this.setState({currentTime})

}) } // ... }

The final piece of ou p oject toda is getting the data back f om the fo m to update the pa ent component. That is, hen the use updates the alues f om the TimeForm component, e'll ant to be able to access the data in the

App component. The TimeForm component al ead handles this p ocess fo

us, so e just need to implement ou fo m functions.

When a piece of state changes on the fo m component, it ill call a p op called onFormChange. B defining this method in ou App component, e can

get access to the latest e sion of the fo m.

In fact, e'll just call setState() to keep t ack of the options the fo m allo s

class App extends React.Component { // ...

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

// ... }

Finall , hen the use submits the fo m clicks on the button or p esses ente in the input field , e'll ant to make anothe e uest fo the time. This means e can define ou handleFormSubmit p op to just call the

fetchCurrentTime() method:

class App extends React.Component { // ... handleFormSubmit(evt) { this.fetchCurrentTime(); } // ... }

T pla ing a ound ith the demo and passing in diffe ent ch onic options. It's actuall uite fun.

In an case, toda e o ked on uite a bit to get emote data into ou app. Ho e e , at this point, e onl ha e a single page in ou single page app. What if e ant to sho a diffe ent page in ou app? Tomo o , e' e going to sta t adding multiple pages in ou app so e can featu e diffe ent ie s.

Edit this page on Github (https://github.com/fullstackreact/30-days-of-react/blob/day-17/post.md)

Client-side Routing

Most, if not all of our applications ill ha e multiple ie s in our

In document 30 Days of React eBook Fullstackio (Page 150-159)