1 of 51

Intro to React

CSCI 344: Advanced Web Technologies

Spring 2023

2 of 51

Announcements

  • Grading up-to-date (except for HW4 – will grade HW4&5 together)
  • HW5 due tonight
  • This week: Refactoring Photo App in React
  • HW6 Posted
  • Tutorial 8: Getting started on HW6
  • Next week: starting the process of building your own REST API

3 of 51

Reflection so far…

  • First: some humor: Gary Burnhardt’s famous JavaScript Wat Video (ffw to minute 1:23).
  • Question for the class: reflect on the code you’ve been writing for HW4 / HW5:
    • Has it been difficult to organize?
    • Does it feel messy?
    • Does it feel difficult to debug?
    • Your thoughts here…

4 of 51

Your thoughts here…

  • It’s so long
  • Spaghetti
  • Functions call functions, etc.

5 of 51

What problems does React solve (Pros)?

Why would you want to use a client-side framework?

  1. Encourages you to abstract logical groupings of HTML, CSS and JavaScript logic into blocks (sometimes called ‘widgets’ or ‘components’)
  2. Standardizes the interfaces and techniques for handling workflow and user interactions (which makes it easier for teams to work together)
  3. Communities can organize around a library and make open-source components and plugins that can facilitate rapid prototyping.
  4. Helps to manage complexity as your app gets bigger.

6 of 51

Could it also make things harder (Cons)?

Why would you not want to use a client-side framework?

  • Steep learning curve
  • Might be overkill for what you need
    1. Sometimes all you need is a light-weight JS function to do the job!
    2. Are you making a bunch of server requests from a single-page application?
    3. Do you have a lot of client-side components that you need to manage?

7 of 51

Overview of React

  1. Do the readings
  2. Intro to JSX
  3. Components
  4. Event Handlers
  5. State management
  6. Activity

8 of 51

Overview of React

  • Do the readings
  • Intro to JSX
  • Components
  • Event Handlers
  • State management
  • Activity

9 of 51

Most Important: Do the readings

Before Friday’s tutorial – please complete the following readings. It will take you a few hours, but you won’t be able to make progress with React without understanding some of the core React conventions and workflow, including:

�These are not optional – and they will help you

10 of 51

Overview of React

  • Do the readings
  • Intro to JSX
  • Components
  • Event Handlers
  • State management
  • Activity

11 of 51

JSX

  1. A syntax extension to JavaScript; works similarly to a template literal
  2. Philosophy: Putting HTML & JS into the same file – via “components” – is easier to reason about. Keeping them separate is confusing.
  3. JSX not required, but suggested when using React. Example:

12 of 51

JSX Syntax

Some syntax things...

  1. camelCase convention for properties and variable names (just like JavaScript)
  2. No quotes around the JSX itself
  3. Quotes around constants
  4. Curly braces instead of quotes around JavaScript expressions
  5. Use className (instead of class) to assign CSS classes

<img className="thumbnail" src={post.image_url} />

13 of 51

JSX Example

<div className="post">

<h2>{post.user.username}</h2>

<img className="pic" src={post.image_url} />

<p>{post.last_updated}</p>

</div>

14 of 51

Overview of React

  • Do the readings
  • Intro to JSX
  • Components
  • Event Handlers
  • State management
  • Activity

15 of 51

React Components

  1. Allow you split the UI into independent, reusable pieces, and think about each piece in isolation (all JS frameworks do this, btw).
  2. A special kind of JavaScript function that:
    1. Accepts arbitrary inputs (called “props”)
    2. Returns a React element (JSX)
  3. All components must start with a capital letter (a naming convention that is enforced)
  4. Props – which are passed into the component – are read-only (immutable)

16 of 51

Components: 2 syntaxes

Components accept a single “props” (which stands for properties) object argument and return a react element. Two syntaxes are functionally the same:

We will be using functional components in this class. Currently there’s a move away from class components.

export function Welcome({name}) {

return <h1>Hello, {name}</h1>;

}

class Welcome extends React.Component {

render() {

return <h1>Hello, {this.props.name}</h1>;

}

}

17 of 51

Using Components

Once you create a component function / class, you can use it like regular HTML syntax (so long as you import the component).

  1. Note the uppercase convention �(lowercase tags treated like regular HTML tags)

// Use the component in another file

import Welcome from './Welcome';

function Welcome(props) {

return <Welcome name="Sarah" />

}

18 of 51

Aside: Functional Programming v. OOP

  • A programming paradigm that relies on “pure functions”
  • A pure function is one whose results are dependent only upon the input parameters, and whose operation initiates no side effect, that is, makes no external impact besides the return value.
  • In other words, makes heavy use of immutability:
    • No variables are updated after they are assigned (makes code easier to reason about)
  • Functions are often passed in as data, and functions are also returned from functions.

19 of 51

Aside: Functional Components Using JavaScript Closures

  • A closure gives you access to an outer function's scope from an inner function (see example).
  • Used to encapsulate variable scope

function init() {

var name = "Mozilla"; // name is a local variable created by init

function displayName() {

// displayName() is the inner function, that forms the closure

console.log(name); // use variable declared in the parent function

}

displayName();

}

init();

20 of 51

Aside: JavaScript Modules (ES Modules)

  • Modules allow you to separate logical groupings of functionality, and given them a private scope (versus having everything on the global scope).
  • You can create public variables, functions, and objects using the “export” keyword. If you don’t use the “export” keyword, than the item is private.
  • You can also import modules and access them in other JavaScript files.

21 of 51

Overview of React

  • Do the readings
  • Intro to JSX
  • Components
  • Event Handlers
  • State management
  • Activity

22 of 51

Handling Events

Let’s just look at the documentation and talk about it...

<button role="switch"

className="like"

aria-checked="false"

onClick={toggleLike}>

Like

</button>

23 of 51

Overview of React

  • Do the readings
  • Intro to JSX
  • Components
  • Event Handlers
  • State management
  • Activity

24 of 51

State and Lifecycle

  1. state variables must be declared for any variables whose changes to them might require a screen redraw
  2. All state variable changes trigger a request for the corresponding component to “redraw itself.” Examples of where you might want to use state:
    • A user likes or bookmarks a post
    • A user adds a new comment to the post
  3. When any of these interactions happens, you will update the component’s state…which will force a redraw.

25 of 51

Update State using the built-in useState() function

import { useState } from 'react';

function Carousel() {

const [index, setIndex] = useState(0); // pass in initial value

}

  • useState taks an initial value as an argument
  • Returns a list with two values: the current state and a setter function
  • See documentation: https://beta.reactjs.org/reference/react/useState

26 of 51

“State” Takeaways

  1. If you update a component’s state, this will automatically trigger a component redraw (for the associated component).
  2. Take advantage of this fact when designing your UI. For instance:
    1. User clicks the heart to like a post
    2. Click event issues a POST request to /api/posts/<id>/likes
    3. If the request is successful, a GET request is issued to /api/posts/<id> to get an updated Post object.
    4. If the request is successful, modify the state to store the updated post.
    5. The updated state automatically redraws the post (which in turn redraws all of the child components).

27 of 51

“Lifting Up” State

  • The state of a component is only accessible to the component (it’s encapsulated)!
  • If you want a state change to “notify” another component (i.e. “lifting up the state”), then your child component needs to be granted access to a function that belongs to the parent of the component (passed to the child as a property)

For example, if your “add new comment” functionality would like to notify a parent component to requery and redraw the post, then the requeryPost() functionality needs to be defined in the parent and then passed down to the the child component (as a property).

28 of 51

Overview of React

  • Do the readings
  • Intro to JSX
  • Components
  • Event Handlers
  • State management
  • Activity

29 of 51

React Set Up: Install Node

You need to install node.js, which will also install npm – the node package manager (analogous to pip)

  1. BEFORE INSTALLING ANYTHING NEW: see if you already have npm installed by typing npm --version
  2. If you have version 8 or higher, you’re fine

30 of 51

Activity

Let’s practice some of these concepts �by building an image carousel…

31 of 51

Wednesday (3/15)

32 of 51

Wednesday Outline

  • A few more JavaScript “convenience” features (that folks have asked about)
  • Finish activity from Monday
  • Intro to React “Effects”
  • Today’s Activity: Modified Carousel that syncs with server data

33 of 51

Wednesday Outline

  • JavaScript “convenience” features
  • Intro to React “Effects”
  • Today’s Activity: Modified Carousel that syncs with server data

34 of 51

Aside: Ways of accessing elements in JavaScript Arrays

// convenient way to set variables from a list:

const myArray = [123, 456, 789, 123456, 66, -11]

console.log(myArray[0]);

console.log(myArray[1]);

// alternative syntax:

const [a, b] = myArray;

console.log(a);

console.log(b);

35 of 51

Aside: Ways of accessing elements in JavaScript Objects

// convenient way to set variables from an object:

const myObj = {a: 123, b: 456, c: 789, d: "hi there" };

console.log(myObj.a);

console.log(myObj.d);

// alternative syntax

const {a, d} = myObj; // only select the ones you want

console.log(a);

console.log(d);

36 of 51

Wednesday Outline

  • JavaScript “convenience” features
  • Finish activity from Monday
  • Intro to React “Effects”
  • Today’s Activity: Modified Carousel that syncs with server data

37 of 51

Lecture 16 Activity

We’re going to pick up where we left off on the Carousel activity. If you weren’t here on Monday, please…

  1. Download the Carousel Exercise starter files
  2. Replace the code inside Carousel.js with the Carousel.js file we completed in class.

Still TODO:

  1. Create the Galleries component
  2. Get the components to talk to one another via their parent (App)

38 of 51

Wednesday Outline

  • JavaScript “convenience” features
  • Finish activity from Monday
  • Intro to React “Effects”
  • Today’s Activity: Modified Carousel that syncs with server data

39 of 51

But how do you request Server data using React?

Recall:

  • React Components are intended to be “pure” (i.e. they can only access data that are passed into them via props)
  • If you want React to “reach outside” of its sandbox, you have to do it in a very particular way in order for React to behave correctly.
  • Specifically, if you want to interact with external system (i.e. via fetch requests, web sockets, etc.) you need to use the built-in useEffect() hook (Effect → think “side effects”).

40 of 51

Effects and the useEffect() hook

Effects are an escape hatch from the React paradigm. They let you “step outside” of React and synchronize your components with some external system like a non-React widget, network, or the browser DOM.

Examples:

  • I want to fetch (POST, GET, DELETE, PATCH, PUT) some data from a server
  • I want to respond to a message that was just received from a chat server (via websocket)
  • I want to coordinate with a JS widget outside of react (e.g. Google Maps, the browser’s built-in audio / video / canvas API)

41 of 51

How to write an Effect

To write an Effect, follow these three steps:

  1. Declare an Effect. By default, your Effect will run after every render (which you most often DO NOT WANT).
  2. Specify the Effect dependencies. Most Effects should only re-run when needed rather than after every render. For example, connecting and disconnecting to a chat room should only happen when the component appears and disappears, or when the chat room changes. You will learn how to control this by specifying dependencies.
  3. Add cleanup if needed. Not relevant for PhotoApp, but definitely relevant for a chat app.

42 of 51

1. Declare an Effect

import { useEffect } from 'react';

function MyComponent() {

useEffect(() => {

// Code here will run after *every* render

});

return <div />;

}

CAVEAT: Because the useEffect function is run after every render, it can easily produce an infinite loop. To avoid, see next slide.

43 of 51

2. Specify the Effect dependencies

Use dependencies to control when the useEffect function is invoked:

To only run it once (on initialization), pass in an empty array:

useEffect(() => {

// ...

}, []);

To run it when one or more properties change, pass in the relevant properties:

useEffect(() => {

// ...

}, [prop1, prop2]);

44 of 51

Relevant Readings

45 of 51

Summary of Key Ideas in React

Components

Components are encapsulated units of logic that help you organize your code.

  • They can only access data that are passed in via props.
  • They return a JSX element

JSX

JSX is React’s version of HTML (see previous slides for syntax rules)

Props

Props (properties) are read-only data fields that are passed into a component from its parent.

State

  • State variables are used when a change to a component’s data ought to trigger a redraw.
  • Use the useState function to generate the variable and a setter function
  • Every change to a state variable causes the component (and all of its child components) to redraw.

Effects

  • To interact with systems / APIs that exists outside of the “pure” Component
  • Use the useEffect function hook to issue external logic
  • useEffect hook runs on every render unless dependencies are specified

46 of 51

Wednesday Outline

  • JavaScript “convenience” features
  • Finish activity from Monday
  • Intro to React “Effects”
  • Today’s Activity: Modified Carousel that syncs with server data

47 of 51

Carousel + External Data Activity

48 of 51

Preview of Tutorial 8 & Homework 6

49 of 51

Preview of Tutorial 8 & Homework 6

Phase 1

  1. Draw boxes around the components
  2. Create a static version of everything

Phase 2

  • Figure out which aspects of the component (if any) will change based on a user interaction
  • Decide where your state should live
  • Figure out how to pass data to child components (via props)

50 of 51

What are the

components?

51 of 51

What are the

components?