Section 1

Introduction to React

Learning Objectives

  • Describe why React is so popular and in high demand
  • Describe the history of React
  • Describe what is React in terms of code organization
  • Explain what is JSX
  • Explain what is state
  • Build a simple React app

Components

  • A React app's UI consists of components.
  • In React, we build an app's UI by composing built-in and user-defined components.
  • React's built-in components are often referred to as React Elements and are used to emit in the HTML page DOM actual elements like <div>, <h1>, etc.
  • The custom components we code are going to be used a lot like HTML tags. For example, in the diagram above, the UI is being built with tags like <HomePage>, <SearchBar>, <EmployeeList>, etc.
  • Ultimately, our React components must contain React Elements if we want anything to appear on the page.
  • React Elements can be styled using CSS and are the components that we will add event listeners to for responding to user interaction.
  • Components that create the UI are created using 100% JavaScript. There is no HTML markup in React components, just something that looks like it...


JSX

  • Although a React component's UI is ultimately defined by JavaScript, there is a better way to define the UI using a special syntax known as JSX.
  • The syntax is an XML-based syntax that looks like HTML - as it should since HTML is also based on XML.
  • Since our browsers do not understand JSX, it must first be transpiled (converted) into pure JS.


State and Props

  • Like most applications, a React component may have state (data/information).
  • State can only be changed by the component that "owns" that state.
  • When a component's state is changed, that entire component is re-rendered, including all of its child components.
  • A "stateful" component passes any state needed by child components as props.
  • Props are accessible as key/value pairs on a props object. This props object is passed to the component every time it is rendered.
  • Props in a component are always read-only.


Rendering

Consider that most state is held at or near the top of the component hierarchy. Further, you now know that a component, and all of its children are re-rendered if any state changes.

Yeah, rendering happens frequently in a React app (whenever state changes), but thanks to React's ingenious design, it's very fast and efficient because:

  • First, React renders to an in-memory representation of the DOM, known as the Virtual DOM.
  • After the rendering is done, React compares the latest Virtual DOM to the previous Virtual DOM and computes only the "difference", known as the diff.
  • React then updates the browser's actual DOM with the actual changes (the computed diff).



React Tic-Tac-Toe

We will be focusing on writing React Functional Components, this is the more modern and current standard way of writing React code.

There is an older still used Class based syntax. We recommend to first focus on getting comfortable and master React development with the Functional Syntax then revisit the class syntax at that point when necessary (if working on older code bases).

in app.js

Let's render an h1 inside our App component in App.js

import logo from './logo.svg';
import './App.css';

function App() {
return (<h1> React Tac Toe </h1>);
}

export default App;

NOTE FOR STUDENTS WHO RESEARCH With React 17 and later importing React is no longer required for components that aren't using any hooks, so when you look at old code and you see react imported and not being used thats why, React 17 eliminates that need.

When we refresh our view "Hello World" should be replaced with "React Tac Toe".

If we've installed React Dev tools, we can go over to the React tab and see our component

react dev tools

Making a Component inside another component

According to our mockup, our App will have 4 components

  • header
  • two player components
  • board

With react, we can only render ONE component. That component can have numerous components inside of it.

Let's make our header component by doing the following:

  • create a "components" folder in "src" to house all our non-App components
  • create a file src/components/Header.js

NOTE You can write multiple components in one file, but it is convention that each component get its own file in the components folder.

function Header() {
return (<h1> React Tac Toe </h1>);
}

export default Header;

To use this component we need to:

  • import it into app
  • use it in the JSX of the app component, using components looks a lot like using HTML!
import Header from "./components/Header";
import './App.css';

function App() {
return (<Header/>);
}

export default App;

We still haven't changed how things should look so let's use the dev tools to check everything is in order:

react dev tools

Let's make a player scoreboard

  • create a new file in "components" called Player.js
function Player() {
  return (
      <div>
        <h2>Player </h2>
        <h3>Wins: </h3>
      </div>
    )
}

export default Player;

And have that component render in our app:

import Header from "./components/Header";
import Player from "./components/Player";
import "./App.css";

function App() {
return (
  <div>
    <Header />
    <Player />
  </div>
);
}

export default App;

Since a main feature of React is reusable components we can just copy our Player again:

import Header from "./components/Header";
import Player from "./components/Player";
import "./App.css";

function App() {
return (
  <div>
    <Header />
    <Player />
    <Player />
  </div>
);
}

export default App;

two players

A Sneak Peak of a Lesson in the Near Future

We know we have a player X and a player O, and we want to be able to customize our components. We can pass custom properties to our Player components, using props (short for properties). props is a special term in React. Let's see it in action.

Let's make a custom prop called whichPlayer and pass the appropriate player name

import Header from "./components/Header";
import Player from "./components/Player";
import "./App.css";

function App() {
return (
  <div>
    <Header />
    <Player whichPlayer='x'/>
    <Player whichPlayer='o'/>
  </div>
);
}

export default App;

Now, we need to access these properties inside our Player component. Our player component is a child of App, and thus has access to props. Don't worry if this doesn't make sense yet. We'll be returning to this concept over and over again and it'll start to come together.

// Props are passed as object argument to our component, so we must define a parameter to receive it
// conventionally the parameter is called props
function Player(props) {
  return (
      <div>
        <h2>Player {props.whichPlayer} </h2>
        <h3>Wins: </h3>
      </div>
    )
}

export default Player;

Now we can see our custom property whichPlayer rendering with its value, depending on which component it is:

Props

Let's make one more component for our App, the board:

  • make a Board.js in components
function Board(props) {
  return (
      <div>
        the board!
      </div>
    )
}

export default Board;

Don't forget to add the Board component in our App

import Header from "./components/Header";
import Player from "./components/Player";
import Board from "./components/Board";
import "./App.css";

function App() {
return (
  <div>
    <Header />
    <Player whichPlayer="x" />
    <Player whichPlayer="o" />
    <Board/>
  </div>
);
}

export default App;

You Do:

On your own, and then we'll review ~ 10 minutes

  • make one more component called Square, made up of a div, inside the div put an h4 element, inside the h4 put some text like the word square
  • gotcha! divs have a height and width of 0 when they are empty. Be sure to put in an h4 and some text
  • render 9 squares inside the Board
  • Extra - Read ahead to learn how to incorporate CSS

CSS & React

Right now we have all the right elements, but we need some style to make it look like a proper tic tac toe game, let's try to make it look like this:

expected final appearance

We can create as many CSS files as we want in the src folder, and as long as we import the css file in at least one component, then the styles will be applied to our whole project (some people like to make a css file for each component for organization, but let's not). For now let's just focus on using one stylesheet.

  • create src/styles.css
  • import styles.css into App.js
import Header from "./components/Header";
import Player from "./components/Player";
import Board from "./components/Board";
import "./styles.css";

function App() {
return (
  <div>
    <Header />
    <Player whichPlayer="x" />
    <Player whichPlayer="o" />
    <Board/>
  </div>
);
}

export default App;

Let's add a little starting style to make sure everything is linked correctly

:root {
--dark-cerulean: #124e78;
--maastricht-blue: #0b132b;
--yankees-blue: #1C2541;
--sea-serpent: #5bc0be;
--aquamarine: #6fffe9;
--react: #00d8ff;
}

html {
background: var(--yankees-blue);
}
body {
margin: 0;
font-family: 'Montserrat', sans-serif;
color: white;
}

Let's add some classes to target parts of our components

app.js

Player:

function Player(props) {
  return (
      <div className={props.whichPlayer}>
        <h2>Player {props.whichPlayer} </h2>
        <h3>Wins: </h3>
      </div>
    )
}

export default Player;

Board:

import Square from "./Square"

function Board(props) {
  return (
      <div className="board">
        <Square/>
        <Square/>
        <Square/>
        <Square/>
        <Square/>
        <Square/>
        <Square/>
        <Square/>
        <Square/>
      </div>
    )
}

export default Board;

Square:

function Square(props) {
  return (
      <div>
        <h4>square</h4>
      </div>
    )
}

export default Square;

We can use a combination of flexbox and css grid to complete the look

.container > div {
display: flex;
background: var(--yankees-blue);
flex-wrap: wrap;
justify-content: space-around;
min-height: 60vh;
align-items: flex-start;

}

.board {
flex-basis: 60%;
display: grid;
grid-template-columns: 15vw 15vw 15vw;
grid-template-rows: 15vw 15vw 15vw;
color: white;
justify-items: stretch;
justify-content: center;
}

.board  div {
display: flex;
align-items: center;
border: 3px solid var(--react);
}

h4 {
text-align: center;
flex-basis: 100%;
align-self: center;
}

.X, .O {
flex-basis: 45%;
text-align: center;
}

.X {
color: var(--sea-serpent);
}

.O {
color: var(--aquamarine);
}
h1 {
flex-basis: 60%;
color: var(--react);
text-align: center;

}

Extra

There are newer ways to incorporate CSS into react. You can read about 4 Ways to style react components and try to swap out our style sheet for one ore more of these methods

Copyright © Per Scholas 2023