Loading

ReactJS

Victoria Budyonnaya

This is a live streamed presentation. You will automatically follow the presenter and see the slide they're currently on.

React JS

Agenda

  • What does a browser do
  • About React
  • React Basics
  • JSX
  • Virtual DOM
  • Components
  • React Details

React details

  • Styling
  • HOC & Fragments
  • Props & PropTypes
  • State
  • Routing
  • Lifecycle methods
  • Refs
  • Error Boundary

What does a browser do?

The main function of a browser is to present the web resource you choose, by requesting it from the server and displaying it in the browser window. 

Rendering engine

initial

Painting the render tree

Layout of the render tree

Render tree construction

Parsing HTML to construct the DOM tree

Reflow

RePAint

When the changes affect document contents or structure, or element position, a reflow happens.

  1. DOM manipulation;
  2. Contents changes, including text changes in form fields;
  3. Calculation or altering of CSS properties;
  4. Adding or removing style sheets;
  5. Changing the "class" attribute;
  6. Browser window manipulation;
  7. Pseudo-class activation (:hover).

When changing element styles which don't affect the element's position on a page (such as background-color, border-color, visibility), the browser just repaints the element again with the new styles applied (that means a "repaint" or "restyle" is happening).

React

  • Created in March 2013 By Facebook Team  (v 16.8.3)
  • 2 131 256 downloads last week at NPM (2018)
  • 6 119 017 downloads last week at NPM (2019)
  • 123583 stars at Github

A JavaScript library for building user interfaces

ReactJS is only a view layer.

We built React to solve one problem: building large applications with data that changes over time

Main points

  • React is a JavaScript library for building user interfaces
  • React codebase consists of components, which may be written with the help of JSX or not;
  • React uses a concept called Virtual DOM. That selectively renders subtrees of nodes based upon state changes;
  • React also presents some useful features to handle events.

Benefits

  • Virtual DOM;
  • One-direction data flow;
  • Reusable components;
  • Great Developer Tools;
  • Huge and growing ecosystem;
  • Easy to learn, easy to use
  • Dev Community

REACT basics

"Hello world"

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

const element = React.createElement(
	"h1", 
	{className: "title"},
	"Hello World!"
);

ReactDOM.render(element, document.getElementById("root"));

Elements are the smallest building blocks of React apps.

ReactDOM.render (nextElement, container, [callback]);

/*
* @param {ReactElement} nextElement element to render.
* @param {DOMElement} container DOM element to render into. 
* @param {function} callback function triggered on completion.
*/

React Element is a plain JS object

const element1 = React.createElement (
  "h1", 
  {
    id: "id_001", 
    className: "main_title", 
    key : "001"
  },
  "Hello World!"
);
console.log(element1);

{
  type: "h1",
  props: {
    id: "id_001", 
    className: "main_title", 
    children: "Hello world"
  },
  key: "001",
  ref: ""
}
const elem1 = React.createElement(
	"h1",
	{id: "id_001", className: "my_title"},
	"Hello World!"
);
const elem2 = React.createElement(
	"div",
	{id: "id_002", className: "my_desc"},
	"Some description..."
);

const root = React.createElement("div", null, elem1, elem2);

ReactDOM.render(root, document.getElementById("container"));

JSX

JSX is a XML-like syntax extension to ECMAScript

const helloWorld = <div> Hello World! </div>;

HelloWorld.jsx

React.createElement("div", null,
    React.createElement( "h1", null, "Title"),
    React.createElement("div", {className: "child1" },
        React.createElement("div", { className: "child1_1" }, "Sometext"),
        React.createElement("div", { className: "child1_2" }, "Sometext")
    ),
    React.createElement("div", {className:"child2"}, 
        React.createElement("ul", null, 
            React.createElement("li", null, "1"), 
            React.createElement("li", null, "2"), 
            React.createElement("li", null, "3")
        )
    )
);
<div>
  <h1>Title</h1>
  <div class ="child1">
    <div class = "child1_1">Some text</div>
    <div class = "child1_2">Some text</div>
  </div>
  <div class = "child2">
    <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
    </ul>
  </div>
</div>

ReactElement tree

HTML

JSX compiles to regular JS (NOT TO HTML), so you don’t need to use it, in case you don’t want to

<div> Hello World! </div> 
React.createElement( 
	"div", 
	null, 
	"Hello World!" );

JSX

JS

React's JSX uses the upper vs. lower case convention to distinguish between local component classes and HTML tags

<Hello> Hello World! </Hello> 
React.createElement( 
	"Hello", 
	null, 
	"Hello World!" );

JSX

JS

JSX is an EXPRESSION

const getGreeting = user => {
  if (user){
    return <h1>Hello, Friend</h1>
  }
  return <h1> Hello, Stranger</h1>
}

JS statements in JSX

<div>{ if (true) return "Hello"}</div>
<div>{true ? "Hello" : null}</div>
<div className = {"myClass"}></div>

<div className = "myClass" ></div>

<div className></div>
React.createElement(
    "div", 
    {className: "myClass"}
);

React.createElement(
    "div",
    {className: "myClass"}
);
	
React.createElement(
    "div",
    {className: true }
); 	

Booleans, Null, and Undefined Are Ignored

<div/>

<div></div>

<div>{false}</div>

<div>{null}</div>

<div>{true}</div>


<div>
   { showHeader && <div>Header</div> }
   <div>Content</div>
</div>

KEY

 

var data = ["item1", "item2", "item3", "item4", "item5"];

var list = <ul> {data.map((elem) => <li>{elem}</li>)} </ul>

ReactDOM.render(list, document.getElementById("container"));

Virtual dom

Virtual DOM is a JavaScript representation of the DOM. React Element is the main building block of Virtual DOM.

 

The process of updating your UI to match your application state

The Virtual DOM is an abstraction of the HTML DOM. It is lightweight and detached from the browser-specific implementation details. Since the DOM itself was already an abstraction, the virtual DOM is, in fact, an abstraction of an abstraction.

Virtual DOM Process

Components

Components let you split the UI into independent, reusable pieces, and think about each piece in isolation.

 

Components are functions that accept arbitrary inputs (props) and return React elements describing what should appear on the screen

const welcomeMessage = (props) => (<h1>Hello {props.name}</h1>)
class WelcomeMessage extends Component { 
	render() { 
		return <h1>Hello, {this.props.name}</h1>; 
	} 
}

Functional Component

Class Component

class App extends Component {  
  constructor() {    
    super();    
    this.state = { counter: 0 };  
  }
  
  render() {
  	return <div className="container">
	  <div className="alert alert-success">
	    {this.state.counter}
	  </div>
	</div>
  }
}

Class component

When to use a Class Component over a Function Component?

If the component needs lifecycle methods then use class component otherwise use function component.

 

React.PureComponent is exactly the same as React.Component except that it handles the shouldComponentUpdate() method.

When props or state changes, PureComponent will do a shallow comparison on both props and state.

Component on the other hand won't compare current props and state to next out of the box. Thus, the component will re-render by default whenever shouldComponentUpdate is called.

Create react app

npm install -g create-react-app
create-react-app my-app 

//or

npx create-react-app my-app

cd my-app 
npm start

Styling

  • Inline styles
  • CSS/Sass stylesheets
  • CSS Modules
  • Styled Components

Inline styles

const divStyle = {
  margin: '40px’,
  border: '5px solid pink’
};

<div style={divStyle}>
    <p style={{color:'#FF5733', backgroundColor: 'black’}}>
    	Error message
    </p>
    <p style={{margin: 30}}> Welcome message goes here</p>
</div>

CSS/sass stylesheet

//footer.scss
.FooterMessage {
 margin: 40px;
 border: 5px dotted red;
 border-radius: 5px;
}

//component.jsx
import React from 'react';
import './footer.scss';
let Footer
export default Footer = () => 
  	<p className='FooterMessage'>This is footer</p>

CSS modules

//footer.module.scss
.content {
  font-size: 15px;
  text-align: center;
 }

//component.jsx
import styles from './footer.module.scss';
const Paragraph = () =>
    <p className={styles.content}>
      	This is a paragraph with CSS module
    </p>
export default Paragraph;

styled components

import styled from 'styled-components';
const Button = styled.button`
  background: transparent;
`;
const Container = styled.div`
  text-align: center;
`
render(
<Container>
	<Button> This is styled button</Button>
</Container>
);

High Order components

 A higher-order component (HOC) is a function that takes a component and returns a new component.

It's a pattern that is derived from React's compositional nature.

  • Code reuse, logic and bootstrap abstraction.
  • Render hijacking.
  • State abstraction and manipulation.
  • Props manipulation.
function withNewTitleHOC(WrappedComponent) {
   return class Test extends Component {
     render() {
      const newProps = {
       title: ‘This is New Title’
     }
      return <WrappedComponent {...this.props} {...newProps} />
    }
   }
}

Fragments

Assumption:

It’s ok to OK to use divs in large React application

 

Reality:

Ok, I’ll use it here, and here, and here… Wait a minute where is my component?

  • Fragments are a bit faster and use less memory by not creating an extra DOM node. This only has a real benefit on very large and deep trees.
  • Some CSS mechanisms like Flexbox and CSS Grid have a special parent-child relationships, and adding divs in the middle makes it hard to keep the desired layout.
  • The DOM Inspector is less cluttered.

Why Fragments are better than divs?

Props & State

State

State of a component is an object that holds some information that may change over the lifetime of the component.

 

We should always try to make our state as simple as possible and minimize the number of stateful components.

 

State is similar to props, but it is private and fully controlled by the component.

It is not accessible to any component other than the one that owns and sets it.

Stateful Component

 

  • Know how everything works
  • Just a container for other components
  • Provide application data
  • Perform data fetching

Stateless Component

 

  • Know how to display received data

  • Receive and operate only with props

  • Usually the same as functional components

Parent-child communication

The best ways how to communicate between parents and children is to use state and props, or state management libraries like Redux, MobX etc

Communication with callbacks passed via props from stateful components to their children to mutate state of the parent component

Proptypes

  • Nice library to type check your application
  • Help with finding issues at early stages ( while development) 
  • Checks JS types, react elements, many items, required props and so on
  • Won’t help in production mode
  • Flow or TypeScript provide more features

but

YourComponent.propTypes = { 
  optionalArray: PropTypes.array, 
  optionalBool: PropTypes.bool, 
  optionalFunc: PropTypes.func, 
  optionalNumber: PropTypes.number, 
  optionalObject: PropTypes.object, 
  optionalString: PropTypes.string, 
  optionalSymbol: PropTypes.symbol,

  reqString: PropTypes.string.isRequired
}

Routing

A single-page application (SPA) is a website that re-renders its content in response to navigation actions (e.g. clicking a link) without making a request to the server to fetch new HTML.

The point of a single-page application is to avoid requests hitting the server (during navigation). It is ok to load a new piece data from server for a new route (via AJAX) BUT we need to avoid to load HTML/CSS/JS content during navigation

How?

REACT ROUTER

npm i react-router-dom

Typically apps will use one of the high-level routers:

  • <BrowserRouter>
  • <HashRouter>
  • <MemoryRouter>
  • <NativeRouter>
  • <StaticRouter>
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { HashRouter as Router, Route, Link } from 'react-router-dom';

const Home = () => <p>Home</p>;
const About = () => <p>About</p>;
const NotFound = () => <p>404 Not Found</p>;

export class App extends React.Component {
  render() {
    return (
    <Router>
      <Route exact path="/" component={Home} />
      <Route path="/about" component={About} />
      <Route component={NotFound} /> // 404 page
    </Router>
    );
  }
}

To navigate - use <Link> or <NavLink> componants from react-router-dom

import { NavLink Link } from 'react-router-dom';

<NavLink to="/about"> About </NavLink>
<Link to="/"> Home </Link>

Nested routes

Path prop of <Route>

const App = () => (
  <BrowserRouter>
    <div>
      <Route path="/tacos/:id" component={Tacos} />
    </div>
  </BrowserRouter>
);


const Tacos = (props) => (
  <div>
    <Route path={props.match.params.id + "/carnitas"} component={Carnitas} />
  </div>
);

<Redirect> component will navigate to a new location

LifecyclE Methods

 

The component lifecycle has three distinct lifecycle phases:

 

Unmouting

Updating

Mouting

render( ) is the only required method in a component

The component is ready to mount in the browser DOM.

In this phase, the component get updated in two ways, sending the new props and updating the state.

The component is not needed and get unmounted from the browser DOM.

Mounting

constructor()

 only used for two purposes:

  • Initializing local state by assigning an object to this.state.
  • Binding event handler methods to an instance.

If you don’t initialize state and you don’t bind methods, you don’t need to implement a constructor for your React component.

Avoid introducing any side-effects or subscriptions in the constructor, use componentDidMount() instead.

static getDerivedStateFromProps()

render()

componentDidMount()


getDerivedStateFromProps exists for rare use cases where you need derived state.

Mounting

render()

 only required method in a class component. When called, it should examine this.props and this.state and return one of the following types:

  • React elements
  • Arrays and fragments
  • String and numbers
  • Booleans or null

 

render() will not be invoked if shouldComponentUpdate() returns false

Mounting

componentDidMount()

executed after first rendering, immediately after a component is mounted (inserted into the tree).

 

This method is a good place to make all AJAX requests, DOM or state updates, and set up event listeners and any subscriptions.

If you do that, don’t forget to unsubscribe in componentWillUnmount().

Updating

shouldComponentUpdate()

determines if the component will be updated or not.

By default it returns true.

If you are sure that the component doesn't need to render after state or props are updated, you can return false value.

 

It is a great place to improve performance as it allows you to prevent a re-render if component receives new prop.

 

Do not rely on it to “prevent” a rendering, as this can lead to bugs.

Consider using the built-in PureComponent instead of writing shouldComponentUpdate() by hand.

PureComponent performs a shallow comparison of props and state, and reduces the chance that you’ll skip a necessary update.

Updating

getSnapshotBeforeUpdate()

executed right before rendered output is committed to the DOM.

 

Any value returned by this will be passed into componentDidUpdate().

This is useful to capture information from the DOM, for example scroll position.

Updating

componentDidUpdate()

mostly it is used to update the DOM in response to prop or state changes.

 

This will not fire if shouldComponentUpdate() returns false.

Legacy Lifecycle Methods

UNSAFE_componentWillMount() executed before rendering and is used for App level configuration in your root component

 

UNSAFE_componentWillReceiveProps() executed when particular prop updates to trigger state transitions

 

UNSAFE_componentWillUpdate() executed before re-rendering the component when there are props & state changes confirmed by shouldComponentUpdate() which returns true

REF

Almost the same as getElementById, needed for:

  • Managing focus, text selection, or media playback.
  • Triggering imperative animations.
  • Integrating with third-party DOM libraries.

 

Special properties allowing to refer to the corresponding instance

Give ability to get access to the DOM node.

React automatically destroy refs (or set null if you use callbacks) if element was destroyed.So don’t worry about memory leaks.
Don’t make sense to use ref for functional components because they have no instances.

 

Allow get access to the child component instance using refs. Method also can be called but it’s not recommended.

ERROR boundary

Error boundaries are components that

  • catch JavaScript errors anywhere in their child component tree
  • log those errors
  • display a fallback UI instead of the component tree that crashed.

 

A class component becomes an error boundary if it defines new lifecycle methods: componentDidCatch(error, info) or static getDerivedStateFromError() 

<ErrorBoundary>
	<YourComponent/>
</ErrorBoundary>

Below are the cases in which error boundaries don't work

1. Inside Event handlers

2 .Asynchronous code using setTimeout or requestAnimationFrame callbacks

3. During Server side rendering

4. When errors thrown in the error boundary code itself

In the past, JavaScript errors inside components used to corrupt React’s internal state and cause it to emit critical errors on next renders.

 

React did not provide any way to handle them gracefully in components, and could not recover from them.

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }
  componentDidCatch(error, info) {
    // You can also log the error to an error reporting service
    logErrorToMyService(error, info);
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children; 
  }
}
<ErrorBoundary>
	<YourComponent/>
</ErrorBoundary>

Thanks!

AND GOOD LUCK

Simple React App from lecture

Full version of App from lecture

React Crash Cource

1.5 hour YouTube video to clear some basic gaps

Made with Slides.com