Giter VIP home page Giter VIP logo

intro-to-react's Introduction

Intro To React Workshop

This hour-long workshop was developed for the Open Source Dev Garage as a part of Facebook's 2017 developer conference, F8.

For best results, watch the 48-minute workshop video and follow along in this guide.

Class Video Walkthrough

By the end of the workshop, we will have a simple production-ready weather app:

Snapshot of the final weather app

Create your first app

First you'll need node.js and a JavaScript editor like atom.

Next, open a terminal and install create-react-app:

npm install -g create-react-app

(Depending on your node installation, you may need to add "sudo" at the front of the npm install -g command)

Now we will create our sample Weather app:

create-react-app weather

Now a bunch of dev tools are getting installed, which will help you build your React app. When it completes, you can run the following to start your app:

cd weather
npm start

Now, your new app will load in your browser!

Snapshot of the final weather app

Components and Props

Lets take a look at the basic app that was generated for us. In your editor, open weather/src/App.js. The app currently looks like this:

class App extends Component {
  render() {
    return (
      <div className="App">
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>Welcome to React</h2>
        </div>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
      </div>
    );
  }
}

Our whole app is in one component, and the render function is at the heart of it. Try modifying some text, save, and watch the app automatically show those changes!

Now lets go ahead and make a new component, WeatherDisplay. The render function is the heart of the component because it defines what will be displayed. For now, lets just display a <h1> HTML tag, with some text inside.

class WeatherDisplay extends Component {
  render() {
    return (
      <h1>Displaying some Weather!</h1>
    );
  }
}

Lets modify our App component to use this new one.

class App extends Component {
  render() {
    return (
      <div className="App">
        <WeatherDisplay zip={"12345"} />
      </div>
    );
  }
}

As you can see, we are passing data into WeatherDisplay. This data is a prop, called "zip". We can modify our component to display the data being passed in:

class WeatherDisplay extends Component {
  render() {
    return (
      <h1>Displaying weather for city {this.props.zip}</h1>
    );
  }
}

Near the top of the file, lets add some different places that we might want to display weather for:

const PLACES = [
  { name: "Palo Alto", zip: "94303" },
  { name: "San Jose", zip: "94088" },
  { name: "Santa Cruz", zip: "95062" },
  { name: "Honolulu", zip: "96803" }
];

Now, upgrade the App's render function to iterate over each place, and render a <button> tag for it.

return (
  <div className="App">
    <WeatherDisplay zip={"12345"} />
    {PLACES.map((place, index) => (
      <button
        key={index}
        onClick={() => {
          console.log('Clicked index '+index);
        }}
      >
          {place.name}
      </button>
    ))}
  </div>
);

We are creating an array of a elements for it, and the key prop is used to tell React what is the order of the elements in the array.

There is also an onClick event handler, where we log the click to the console. You can see the log statements by opening the "Developer Tools" in your browser. Your app should now look like this:

Snapshot of the app with props

At this point, your App.js file should look like this.

State

We want our app to be able to switch between places, so we can use state to keep that data in our App component.

First, lets add a constructor function that will use the normal class super function, and then set up the initial this.state:

constructor() {
  super();
  this.state = {
    activePlace: 0,
  };
}

Our render function can use the data from this.state when declaring the UI. To change state, we can use the React component's setState method, which will change the state and re-run the render function to get the new UI.

Let's use the this.state and this.setState in our App component:

class App extends Component {
  constructor() {
    super();
    this.state = {
      activePlace: 0,
    };
  }
  render() {
    const activePlace = this.state.activePlace;
    return (
      <div className="App">
        {PLACES.map((place, index) => (
          <button
            key={index}
            onClick={() => {
              this.setState({ activePlace: index });
            }}
          >
              {place.name}
          </button>
        ))}
        <WeatherDisplay
          key={activePlace}
          zip={PLACES[activePlace].zip}
        />
      </div>
    );
  }
}

Snapshot of the weather app with changing state

At this point, your App.js file should look like this.

Lifecycle Methods and Data Fetching

Sometimes we want to add imperative code that gets called at certain times in our component's lifetime. The lifecycle methods of a React component allows us to write additional code for these cases.

In this example, we want to make an API call when the component first shows up on screen, so we will add code to componentDidMount. Lets update the WeatherDisplay component to the following:

class WeatherDisplay extends Component {
  constructor() {
    super();
    this.state = {
      weatherData: null
    };
  }
  componentDidMount() {
    const zip = this.props.zip;
    const URL = "http://api.openweathermap.org/data/2.5/weather?q=" +
      zip +
      "&appid=b1b35bba8b434a28a0be2a3e1071ae5b&units=imperial";
    fetch(URL).then(res => res.json()).then(json => {
      this.setState({ weatherData: json });
    });
  }
  render() {
    const weatherData = this.state.weatherData;
    if (!weatherData) return <div>Loading</div>;
    return <div>{JSON.stringify(weatherData)}</div>;
  }
}

Let's improve our render method so we can display the data nicely once it is loaded:

const weather = weatherData.weather[0];
const iconUrl = "http://openweathermap.org/img/w/" + weather.icon + ".png";
return (
  <div>
    <h1>
      {weather.main} in {weatherData.name}
      <img src={iconUrl} alt={weatherData.description} />
    </h1>
    <p>Current: {weatherData.main.temp}°</p>
    <p>High: {weatherData.main.temp_max}°</p>
    <p>Low: {weatherData.main.temp_min}°</p>
    <p>Wind Speed: {weatherData.wind.speed} mi/hr</p>
  </div>
);

Snapshot of the weather app with weather data loading

At this point, your App.js file should look like this.

Installing Components

Our app is still somewhat ugly. We can fix that by adding className props to our divs, and importing some CSS.

Or, we can install a library from npm that will help.

Bootstrap is popular UI toolkit for HTML and CSS. Let's install it, alongside react-bootstrap which provides the React components for it:

npm install --save bootstrap react-bootstrap

In the top of the app file, import the css from the bootstrap module:

import "bootstrap/dist/css/bootstrap.css";

Next, import the components we want to use from react-bootstrap. You can find components on the react-bootstrap site.

import { Navbar, NavItem, Nav, Grid, Row, Col } from "react-bootstrap";

Now, replace the App component's render function to use the bootstrap components:

<div>
  <Navbar>
    <Navbar.Header>
      <Navbar.Brand>
        React Simple Weather App
      </Navbar.Brand>
    </Navbar.Header>
  </Navbar>
  <Grid>
    <Row>
      <Col md={4} sm={4}>
        <h3>Select a city</h3>
        <Nav
          bsStyle="pills"
          stacked
          activeKey={activePlace}
          onSelect={index => {
            this.setState({ activePlace: index });
          }}
        >
          {PLACES.map((place, index) => (
            <NavItem key={index} eventKey={index}>{place.name}</NavItem>
          ))}
        </Nav>
      </Col>
      <Col md={8} sm={8}>
        <WeatherDisplay key={activePlace} zip={PLACES[activePlace].zip} />
      </Col>
    </Row>
  </Grid>
</div>

Snapshot of the app with Bootstrap components

Now our app is starting to look more polished, but it would be nice to have a custom theme. We can install bootswatch to do that.

npm install --save bootswatch

Browse the bootswatch website to find a theme, and install it by replacing the import of bootstrap css with the following. In this case we are using the 'journal' theme.

import "bootswatch/journal/bootstrap.css";

The final, working app should look like this:

Snapshot of the weather app with weather data loading

The final source code of the app is here

Resources and other topics

  • React - Official Documentation
  • React Native - Use the same techniques to build mobile apps for iOS and Android
  • Redux - Manage data in large applications when props become tedious
  • Relay - Easily connect React Components with GraphQL data
  • Jest - Test framework for JS
  • Flow - Static type checker for JS

Deploying - (Extra credit!)

First, publish your app's code to a Github repo. Then, browse to your repo and review the ReadMe file that is generated for your app. There are deployment instructions for many popular services.

One of the easiest services to use is Netlify, especially when you use the "continuous deployment" mechanism.

intro-to-react's People

Contributors

ericvicenti avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.