Workshop by Nick Turner
https://github.com/nick-turner/react-dojo
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.
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.
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
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.
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:
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.
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
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.
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);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.
class Welcome extends React.Component {
render() {
return <h1>Hello {this.props.name}!</h1>;
}
}We can also create React components using an ES6 class.
{props.name} becomes {this.props.name}
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.
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.
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.
.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);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.
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.