How to Learn ReactJS Quickly

#WEEK2DAY6: User Interactions, Component Life Cycles, Routing

Jake Batsuuri
3 min readJun 2, 2021

This is still a pretty basic use of React and its ecosystem. But I think with this and everything we know so far. We should be able to at least build and deploy a simple website, not a web app, but a website that is beautiful and impressive.

Handling User Interaction

Simplest Scenario

import React from 'react';class Product extends React.Component {
showPrice() {
alert(this.props.item.price);
}
render() {
return <li onClick={() => this.showPrice()}>
<h3>{this.props.item.name}</h3>
<p>{this.props.item.description}</p>
</li>;
}
}
export default Product;

HTML vs JSX

HTML events:

<li onclick="...">...</li>

JSX:

<li onClick=...>...</li>

HTML invocation of functions is a string:

<li onclick="showPrice()">...</li>

JSX:

<li onClick={showPrice}>...</li>
<li onClick={() => this.showPrice()}>

HTML default behaviour prevention in JSX:

<a href="#" onClick={(e) => { e.preventDefault();
console.log("Clicked");}}>Click</a>

Change State on Event Trigger

Changing the current components state will be easy, but how do you change the state of a parent component?

Since React is unidirectional down, you can’t go up and access stuff. However you can pass down methods from parents to children. Then the child component can invoke this passed method.

import React from 'react';
import './Catalog.css';
import ProductList from './ProductList';
class Catalog extends React.Component {
constructor() {
super();
this.state = { products: [] };
fetch("products.json")
.then(response => response.json())
.then(json => {this.setState({products: json})})
.catch(error => console.log(error));
}
select(productCode) {
let productList = this.state.products.map(function(p) {
if (p.code === productCode) {
p.selected = (!p.selected);
}
return p;
});
this.setState({products: productList});
}
render() {
return <div>
<h2>Wine Catalog</h2>
<ProductList items={this.state.products} selectHandler={this.select}/>
</div>;
}
}
export default Catalog;

The the next component does this:

import React from 'react';
import './ProductList.css';
import Product from './Product';
class ProductList extends React.Component {
render() {
let products = [];
for (let product of this.props.items) {
products.push(<Product item={product}
selectHandler={this.props.selectHandler}/>);
}
return <ul>{products}</ul>;
}
}
export default ProductList;

It just passes the method from it’s parent to it’s child. Then finally the lowest component does this:

import React from 'react';
import './Product.css'
class Product extends React.Component {
render() {
let classToApply = this.props.item.selected? "selected": "";

return <li onClick={() => this.props.selectHandler
(this.props.item.code)}
className={classToApply}>
<h3>{this.props.item.name}</h3>
<p>{this.props.item.description}</p>
</li>
}
}
export default Product;

It calls the parent’s function passed through the prop. The function in the parent uses the setState method, which refreshes React.

Component Lifecycles

Pre Lifecycle

  • Constructor — component doesn’t have access to child components or DOM

Lifecycle (in order of invocation)

  • componentWillMount — component is about to be inserted into the DOM
  • componentWillReceiveProps — before insertion into DOM, but after receiving props from parent
  • shouldComponentUpdate — a method with a return value, that dictates whether the component should continue rendering, has new params nextProps, nextState, can’t set state here
  • componentWillUpdate — right right before render()
  • componentDidUpdate — right after render(), has two params, previousState and previousProps
  • componentDidMount — the component is now inserted into the DOM
  • componentWillUnmount — its called right before being removed from the DOM, can’t use setState() here

Grouped and Use Cases

Mounting: This group contains the events related to DOM manipulation:

  • componentWillMount,
  • componentDidMount, and
  • componentWillUnmount

Updating via props: Events that are triggered when a component is updated via props passed by its parent:

  • componentWillReceiveProps,
  • shouldComponentUpdate,
  • componentWillUpdate, and
  • componentDidUpdate

Updating via setState(): Events triggered when a component is updated via setState():

  • shouldComponentUpdate,
  • componentWillUpdate, and
  • componentDidUpdate

Routing

Our React app is just a single component called App, so how do we simulate page switching?

npm install --save react-router-dom

To add the basic functionality of routing, add this to our index.js:

import React from 'react';
...
import { BrowserRouter } from 'react-router-dom'
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>

, document.getElementById('root'));
registerServiceWorker();

Then we go to our App.js:

import React, { Component } from 'react';
import './App.css';
import Catalog from './Catalog';
import About from './About';
import { Switch, Route } from 'react-router-dom'
class App extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<h1 className="App-title">The Catalog App</h1>
<nav>
<ul>
<li><Link to='/'>Catalog</Link></li>
<li><Link to='/about'>About</Link></li>
</ul>
</nav>
</header>
<Switch>
<Route exact path='/' component={Catalog}/>
<Route path='/about' component={About}/>
</Switch>

</div>
);
}
}
export default App;
  • Catalog at url ‘/’
  • About at url ‘/about/’

Also note that the Link to urls must match the Route urls.

To make sure something always renders, use:

<Route path='/about' render={() => (<About data={someData}/>)}/>

or:

<Route path='/footer' children={() => (<Footer />)}/>

References

References

--

--