1 of 34

CSE331�Lecture 11.2

JavaScript Wrap up

Ardi Madadi �Summer 2021(Based on slides by Kevin Zatloukal, Mike Ernst, Dan Grossman, and many others)

1

2 of 34

Problems

These tools can be used to write Gmail

But it has a number of problems…

  1. Lack of tool support
    • no checking of types, tags, etc.

  • No support for modularity
    • all the code and UI in a single file

  • More boilerplate
    • minimized JS file would change function names

CSE 331 Summer 2021

3 of 34

TypeScript

  • Adds type constraints to the code:
    • arguments and variables

let x : number = 0;

    • fields of classes

quarter: string;

  • tsc performs type checking

  • Created version has type annotations removed

CSE 331 Summer 2021

4 of 34

TypeScript

  • Type system is unsound
    • can’t promise to find prevent all errors
    • can be turned off at any point with any types
      • x as Foo is an unchecked cast to Foo
      • x! casts to non-null version of the type (useful!)

  • Full description of the language at typescriptlang.org

CSE 331 Summer 2021

5 of 34

TypeScript Types

  • Basics from JavaScript:� number, string, boolean, string[], Object

  • But also
    • specific classes Foo
    • tuples: [string, int]
    • enums (as in Java)
    • allows null to be included or excluded (unlike Java)
    • any type allows any value

CSE 331 Spring 2021

6 of 34

TypeScript Example

register-ts/…

CSE 331 Spring 2021

7 of 34

TypeScript

  • Type system is unsound
    • can’t promise to find prevent all errors
    • can be turned off at any point with any types
      • x as Foo is an unchecked cast to Foo
      • x! casts to non-null version of the type (useful!)

  • Full description of the language at typescriptlang.org

CSE 331 Spring 2021

8 of 34

Classes and Event Listeners

  • JavaScript (until ES6) had no classes!
    • but it is still an object-oriented language

  • We can do some of what we need already:

let obj = {f: (x) => x + 1};

console.log(obj.f(2)); // 3

CSE 331 Summer 2021

  • Problem: how would a method update the state (other fields) of the object?

9 of 34

this

  • In expression obj.method(…):
    • obj is secretly passed to method
    • can be accessed using keyword this

  • So this works properly:

let obj = {

a: 3,

f: function (x) { return x + this.a }

};

console.log(obj.f(2)); // 5

CSE 331 Summer 2021

10 of 34

this

  • You can explicitly pass the “this” argument using the call method on a function object:

let obj = {

a: 3,

f: function (x) { return x + this.a; }

};

console.log(obj.f.call(obj, 2)); // 5

console.log(obj.f.call({a:4}, 2); // 6

CSE 331 Summer 2021

11 of 34

this

  • this only passed if you have “obj.” before method(…)

function compute(f) {

return f(2); // no “obj.” so no “this”

}

let obj = {

a: 3,

f: function (x) { return x + this.a; }

};

console.log(compute(obj.f));

CSE 331 Summer 2021

// NaN!

12 of 34

Why should I care about this?

  • We can add listener functions to components,�but they don’t know to pass this!

  • This will not work:

btn.addEventListener(“click”, obj.foo)

  • obj.foo produces a function, which it calls,�but at that point it’s a regular function
    • this is only passed if you put (…) right after it

CSE 331 Summer 2021

13 of 34

How to fix this

  • You can produce a function with this already set by using the bind method of a function object:

btn.addEventListener(“click”,

foo.bind(obj))

  • Inside of another method (where this is already set) the => lambda syntax does this automatically:

btn.addEventListener(“click”,

evt => this.onClick(evt))

CSE 331 Summer 2021

14 of 34

Problems

This is better, but it still has problems…

  1. Still no checking of HTML (opaque strings)

  • Modularity is still poor
    • need to join strings into one big string

  • More boilerplate
    • minimized JS file would change function names
    • need to call btn.addEventListener by hand

CSE 331 Spring 2021

15 of 34

JSX

  • Fix the first problem by adding HTML as a JS type

  • This is supported in .jsx files:

let x = <p>Hi, {name}.</p>;

  • Compiler can now check that this is valid HTML

  • {…} replaced with string value of expression

CSE 331 Spring 2021

16 of 34

JSX Gotchas

  • Put (..) around HTML if it spans multiple lines

  • Cannot use class=“btn” in your HTML
    • class, for, etc. are reserved words in JS
    • use className, htmlFor, etc.

  • Must have a single top-level tag:
    • not: return <p>one</p><p>two</p>;
    • usually fixed by wrapping those parts in a div

CSE 331 Spring 2021

17 of 34

Problems

This is even better, but it still has problems…

  1. Modularity is still poor
    • need to join strings into one big string

  • More boilerplate
    • minimized JS file would change function names
    • need to call btn.addEventListener by hand

CSE 331 Spring 2021

18 of 34

React

  • Regain modularity by allowing custom tags

let app = (

<div>

<TitleBar name=“My App”/>

<EditPane rows=“80” />

</div>);

  • TitleBar and EditPane can be separate modules
    • their HTML gets substituted in these positions

CSE 331 Spring 2021

19 of 34

React

  • Custom tags implemented using classes

class TitleBar extends React.Component {

  • Attributes (name=“My App”) passed in props arg

  • Method render produces the HTML for component

  • Framework joins all the HTML into one blob
    • can update in a single call to innerHTML = …

CSE 331 Spring 2021

20 of 34

React Example

register-react/…

CSE 331 Spring 2021

21 of 34

React State

  • Last example was not dynamic!
    • there was no model
    • (why have classes then?)

CSE 331 Spring 2021

22 of 34

Structure of a React Application

CSE 331 Spring 2021

Model

Listeners

HTML

data and invariants

presentation

events

updates

23 of 34

React State

  • Last example was not dynamic!
    • there was no model
    • (why have classes then?)

  • Components become dynamic by maintaining state
    • stored in fields of this.state
    • call this.setState({field: value}) to update

  • React will respond by calling render again
    • will automatically update the HTML to match the HTML produced by this call

CSE 331 Spring 2021

24 of 34

Example 5

register-react2/…

CSE 331 Spring 2021

25 of 34

Event Listeners

  • Recall the issue with “this” in JavaScript.
    • careful writing onClick={this.handleClick}

  • Three ways to do this properly:

    • onClick={this.handleClick.bind(this)}
    • onClick={(e) => this.handleClick(e)}
    • Make handleClick a field rather than a method:� handleClick: (e) => { … };�Then this.handleClick is okay. (The homework assignment does this instead.)

CSE 331 Spring 2021

26 of 34

Structure of Example React App

Quarter Picker

App

Class

Picker

State:

– quarter

onPick

Props:

– quarter

State:

– classes

quarter

onBack

27 of 34

React State

  • Custom tag also has its own events

  • Updating data in a parent:
    • sends parent component new data via event
    • parent updates state with setState
    • React calls parent’s render to get new HTML
      • result can include new children
      • result can include changes to child props

CSE 331 Spring 2021

28 of 34

Splitting the Model

  • State should exist in the lowest common parent of all the components that need it
    • sent down to children via props

  • Children change it via events
    • sent up to the parent so it can change its state

  • Parent’s render creates new children with new props

CSE 331 Spring 2021

29 of 34

Structure of a React Application

CSE 331 Spring 2021

Model

Listeners

HTML

data and invariants

presentation

events

updates

React Components

30 of 34

Structure of a React Application

  • Model must store all data necessary to generate the exact UI on the screen
    • react may call render at any time
    • must produce identical UI

  • Any state in the HTML components must be mirrored in the model
    • e.g., every text field’s value must be part of some React component’s state
    • render produces

<input type=“text” value={…}>

CSE 331 Spring 2021

31 of 34

React setState

  • setState does not update state instantly:

// this.state.x is 2

this.setState({x: 3});

console.log(this.state.x); // still 2!

  • Update occurs after the event finishes processing
    • setState adds a new event to the queue
    • work is performed when that event is processed

  • React can batch together multiple updates

CSE 331 Spring 2021

32 of 34

React Gotchas

  • render should not have side-effects
    • only read this.state in render

  • Never modify this.state
    • use this.setState instead

  • Never modify this.props
    • read-only information about parent’s state

  • Not following these rules may introduce bugs that will be hard to catch!

CSE 331 Spring 2021

33 of 34

React Performance

  • React re-computes the tree of HTML on state change
    • can compute a “diff” vs last version to get changes

  • Surprisingly, this is not slow!
    • slow part is calls into browser methods
    • pure-JS parts are very fast in modern browsers
    • processing HTML strings is also incredibly fast

CSE 331 Spring 2021

34 of 34

React Tools

  • Use of compilers etc. means new tool set

  • npm does much of the work for us
    • installs third-party libraries
    • runs the compiler(s)

CSE 331 Spring 2021