React 2

More on components

Conditional Rendering

import NoResult from './components/NoResult/NoResult.js';
import ListDisplay from './components/ListDisplay/ListDisplay.js';

function MyComponent(props) {
  let subComponent = null;
  
  if (props.items && props.items.length) {
    subComponent = <ListDisplay items={props.items} />;
  } else {
    subComponent = <NoResult />;
  }
  
  return (
    <div>
    	{subComponent}
    </div>
  );
}

Iteration

function NumberList(props) {
  const listItems = props.numbers.map((number, i) =>
    <ListItem key={i} value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}
  • Docs
  • You should include a key for each item!!
    • can be any unique value
function NumberList(props) {
  return (
    <ul>
      {props.numbers.map((number, i) => <ListItem key={i} value={number} />)}
    </ul>
  );
}

OR

Inter-component Relations

Nesting a Component

Using it:

Nesting Component:

function Item(props) {
	return (
    	<ProductSurround>
        	<h1>{props.title}</h1>
        </ProductSurround>
    );
}
function ProductSurround(props) {
	return (
    	<div style={{ border: '5px solid red', borderRadius: '15px'}}>
        	{props.children}
        </div>
    );
}

Passing Components as props (aka slots)

Sub-Component File

function Component(props) {
  return (<button>{props.left}{props.text}{props.right}</button>);
}
import Icon from './components/icon/icon.js';
import Address from './components/address/address.js';
import SubComponent from './components/child/child.js';

function MyComponent(props) {
  return (
    <div>
    	<SubComponent
    	    left={<Icon name="information" />}
            right={<Icon name="go arrow" />}
            text="Hello"
        />
    </div>
  );
}

Component File

Passing down props wholesale

import SubComponent from './components/child/child';

function MyComponent(props) {
  return (
    <div>
    	<SubComponent {...props} />
    </div>
  );
}

The Parent/Child Relationship

Stateful & State-less Components

demo 

(using the cars API to demonstrate an AJAX GET)

Raising Up State

  • When several components need access to the same piece of information you put that information in the state of a component higher up the tree of components. This is called 'raising up state.
  • Think about 2 normal functions that share data.
    • You'd put the shared data higher up the scope chain, that's basically what's happening here...
  • demo

Controlling Raised State

  • When several components need access to the same piece of information you put that information in the state of a component higher up the tree of components. This is called 'raising up state.
  • Think about 2 normal functions that share data.
    • You'd put the shared data higher up the scope chain, that's basically what's happening here...
  • basic demo
  • intermediate demo

Making a full Website

  • Is a boilerplate

  • Install react-router too (npm install react-router-dom)



 

Including a Component

Component File

Main App File

export default function Item(props) {
	return <p>{props.text}</p>;
}
import ChildComponent from './components/child/child'; // don't need .js
// if the URL is a directory with index.js in, that will be loaded

function App() {
	return (
    	<div>
        	<h1>Heading</h1>
        	<ChildComponent text="Hello" />
        </div>
    );
}

export default App;

Router

What does this mean?

  • It is a way of rendering several elements at once, to make a page.
    • Which set of elements is controlled by URL
    • The router is a whole management system for controlling this behaviour

Client-side Routing

  • React can control the hash part of the URL to keep track of the 'mode' of the app
  • So for example, you could have:
    • https://www.mydomain.com/#/
    • https://www.mydomain.com/#/about
    • https://www.mydomain.com/#/contact
    • https://www.mydomain.com/#/cars
    • https://www.mydomain.com/#/cars/ferarri/scuderia
  • Because of a thing called HTML5 PushState and the History API, this can be changed to look normal, so:
    • https://www.mydomain.com/#/about <-- becomes
    • https://www.mydomain.com/about
  • N.B. You must be able to handle that route server-side

Client-side Routing cont...

About the router

It comes in 3 parts:

  1. A <Router> tag which surrounds the parts you want to respond to the URL changing
  2. <Route> tags [which must be inside a <router> in hierarchy]
    • It responds to the URL changing by mounting the component that you indicate. This includes page load!
    • <Route path="/about" component={About} />
      • must have exact keyword if path is /
  3. <Link> tags [which must be inside a <router> in hierarchy]
    1. They push the router to change its state. When it does so the Route tags are triggered again.
    2. For normal links: <Link to="/cars/ferrari">Ferrari</Link>
    3. They produce <a>s with JS bound to preventDefault, etc.
    4. (Use <NavLink /> if it's for site navigation)