Loading
Victoria Budyonnaya
This is a live streamed presentation. You will automatically follow the presenter and see the slide they're currently on.
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.
initial
Painting the render tree
Layout of the render tree
Render tree construction
Parsing HTML to construct the DOM tree
When the changes affect document contents or structure, or element position, a reflow happens.
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).
We built React to solve one problem: building large applications with data that changes over time
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.
*/
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"));
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>
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!" );
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!" );
const getGreeting = user => {
if (user){
return <h1>Hello, Friend</h1>
}
return <h1> Hello, Stranger</h1>
}
<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 }
);
<div/>
<div></div>
<div>{false}</div>
<div>{null}</div>
<div>{true}</div>
<div>
{ showHeader && <div>Header</div> }
<div>Content</div>
</div>
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 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.
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>;
}
}
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>
}
}
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.
npm install -g create-react-app
create-react-app my-app
//or
npx create-react-app my-app
cd my-app
npm start
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>
//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>
//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;
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>
);
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.
function withNewTitleHOC(WrappedComponent) {
return class Test extends Component {
render() {
const newProps = {
title: ‘This is New Title’
}
return <WrappedComponent {...this.props} {...newProps} />
}
}
}
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?
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
Stateless Component
Know how to display received data
Receive and operate only with props
Usually the same as functional components
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
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
}
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
npm i react-router-dom
Typically apps will use one of the high-level routers:
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>
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
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
only used for two purposes:
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
only required method in a class component. When called, it should examine this.props and this.state and return one of the following types:
render() will not be invoked if shouldComponentUpdate() returns false
Mounting
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
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
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
mostly it is used to update the DOM in response to prop or state changes.
This will not fire if shouldComponentUpdate() returns false.
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
Almost the same as getElementById, needed for:
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 boundaries are components that
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>
Simple React App from lecture
Full version of App from lecture
1.5 hour YouTube video to clear some basic gaps