Introduction to ReactJS

 

Workshop by Nick Turner

 

Getting Started

 

https://github.com/nick-turner/react-dojo

 

 

What is React?

 

React is a JavaScript library for building user interfaces. It is the view layer for web applications.

 

At the heart of all React applications are components. A component is a self-contained module that renders some output.

 

The aim of this course is to get you familiar with writing React components and putting them together to create web applications.

 

Firstly, understanding JSX

JSX an XML like syntax extension for JavaScript.

const element = <h1>Hello World!</h1>;
const element = React.createElement("h1", null, "Hello World!");

The above is an example of JSX. This gets compiled into the following React code.

  • React doesn’t require you to use JSX, but most people find it helpful when working with UI inside the JavaScript code
  • It's like writing plan old regular HTML, which is a big plus point, but it is in fact JavaScript
  • If you make an error in your JSX markup, the compiler will emit an error instead of continuing in silence

Dynamic values

const name = "World";

const element = <h1 className="alert">Hello {name}!</h1>;

Question - Why className on our <h1>?

 

You might have noticed in the above code that we have used "className" instead of just "class" on our <div> element.

 

This is because JSX is JavaScript and not HTML. In JavaScript, class is a reserved kwy-word so we use className instead to indicate that this is a html attribute.

  • Values wrapped in Curly Brackets are evaluated as expressions

  • Values wrapped in Quotes are evaluated as strings

Rendering React elements

import React from 'react';
import ReactDOM from 'react-dom';

const element = <h1>Hello World!</h1>;

ReactDOM.render(element, document.getElementById('root'));
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
    <div id="root"></div>
</body>
</html>

Component will render into the DOM here.

In order to render a React element on the page, first you need to pass both a React element and a root DOM node (ID of an HTML element) to the ReactDOM.render() function.

Functional components

function Welcome () {
  return <h1>Hello World!</h1>;
}

The simplest React component you can create is just a pure JavaScript function, hence the name, Functional Components. 

Note. the workshop examples will be using this style of syntax throughout.

const Welcome = () => {
  return <h1>Hello World!</h1>;
}

or if  you prefer to use ES6 syntax: 

Rendering Functional components

import React from 'react';
import ReactDOM from 'react-dom';

const Welcome = () => {
  return <h1>Hello World!</h1>;
}

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

To render a component, simply wrap the component function name in

angle brackets <>  and pass the component to the ReactDOM.render.

Props - Passing data down

import React from 'react';
import ReactDOM from 'react-dom';

const Welcome = props => {
  return <h1>Hello {props.name}!</h1>;
}

ReactDOM.render(<Welcome name="World" />, document.getElementById('root'));

Props are a means for allowing components talk to each other

  • Props are passed down from Parent-to-child
  • Props are read-only - a component should never modify its own props

Components consuming components

const Message = props => {
  return <h1>Hello {props.name}!</h1>;
}

const Welcome = props => {
  return (
    <div>
      <Message name="World" />
      ... Rest of the page content
    </div>
  )
}

As a general rule of thumb, most applications are going to need to have more than one component and generally those components are going to need to be nested within each other.

Being able to nest components in such a way makes for a highly re-usable UI.

Mapping data

map() is a JavaScript method that creates a new array with the results of calling a function over every array element.

 

We can use this map() to iterate through an array of data, in this case users.

For each user in the array, we return the users name directly into a new array.

const users = [
  { name: "Nick", age: 32 },
  { name: "Andy", age: 16 },
  { name: "Sarah", age: 21 }
];

const userNames = users.map(user => {
  return user.name;
});
  
console.log(userNames);

Looping through data in components

const users = [
  { name: "Nick", age: 32 },
  { name: "Andy", age: 16 },
  { name: "Sarah", age: 21 }
];

const Welcome = props => {
  return (
    <ul>
      {
        props.users.map(user => {
          return <li key={user.name}>{user.name}</li>
        })
      }
    </ul>
  )
}

We can use the map() method we just learnt about to iterate through an array of users and render a list in the browser.

Note: When mapping over data like this, we must pass a "Key" prop containing a unique value to each element new rendered.

Exercise 1

Class components

class Welcome extends React.Component {
  render() {
    return <h1>Hello {this.props.name}!</h1>;
  }
}

We can also create React components using an ES6 class.

  • This is equivalent to the functional component we created previously.
  • ES6 class components have one requirement - they must implement a render function.
  • Props are no longer passed as an argument to the function. Instead we access them via the "this" key word.

​        {props.name} becomes {this.props.name}

State

class Welcome extends React.Component {
  state = {
    users: [
      { name: "Nick", age: 32 },
      { name: "Andy", age: 16 },
      { name: "Sarah", age: 21 }
    ]
  }

  render() {
    return (
      <ul>
        {this.state.users.map(user => <li>{user.name}</li>)}
      </ul>
    )
  }
}

One powerful feature of class components is the ability to persist the state within itself.

Set-State

const users = [ { name: "Nick", age: 32 }, { name: "Sarah", age: 21 } ];

class Welcome extends React.Component {
  state = { users: [] }

  componentDidMount() {
    this.setState({ users: users })
  }

  render() {
    return (
      <ul>
        {this.state.users.map(user => <li>{user.name}</li>)}
      </ul>
    )
  }
}

Set-state is a React internal method that allows us to update the state of a component in a none mutating way. You should always use this method rather than trying to directly mutate the state.

Props - passing actions up

const Form = props => {
  return <a onClick={() => props.addUser({ name: 'Nick' })}>Add User</a>
}

class Welcome extends React.Component {
  state = { users: [] }

  handleAddUser = (user) => {
    this.setState(prevState => {
      return { users: [ ...prevState.users, user ] }
    })
  }

  render() {
    return (
      <div>
        <Form addUser={this.handleAddUser} />
        <ul>{this.state.users.map(user => <li>{user.name}</li>)}</ul>
      </div>
    )
  }
}

If we need to pass data back up from Child-to-Parent we can do it by passing a function as a prop. This code will invoke the function in the parent and set data.

Exercise 2

Filtering data

.filter() is a JavaScript method that creates an array filled with all array elements that pass a test.

 

We can use this filter() to iterate through an array of data, in this case users. For each user in the array, we return the user into a new array ONLY WHEN over 18.

const users = [
  { name: "Nick", age: 32 },
  { name: "Andy", age: 16 },
  { name: "Sarah", age: 21 }
];

const filteredUsers = users.filter(user => {
  return user.age > 18;
});

console.log(filteredUsers);

Filtering data in components

const users = [
  { name: "Nick", age: 32 },
  { name: "Andy", age: 16 },
  { name: "Sarah", age: 21 }
];

const Welcome = props => {
  const filteredUsers = users.filter(user => {
    return user.age > 18;
  });
  
  return (
    <ul>
      {filteredUsers.map(user => <li>{user.name}</li>)}
    </ul>
  )
}

We can use the filter() method we just learnt about to iterate through an array of users and render a list in the browser for users who are over 18.

Exercise 3

Fetching data

fetch(`https://api.example.com`)
  .then(response => response.json())
  .then((result) => {
    console.log(result);
    // Do something with the result...
  })
  .catch((error) => {
    console.log(error);
    // Do something with the error...
  })
  .finally(() => {
   // Do something when everything completed...
  });

The Fetch API provides an interface for fetching resources (including across the network). It will seem familiar to anyone who has used XMLHttpRequest, but the new API provides a more powerful and flexible feature set.

Exercise 4

Exercise 5

Made with Slides.com