getBoundingClientRect() method as argument (problem-a)
Do a search and see the example:
https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect
Modules are self-contained, isolated scripts that are able to run in their own namespace (without polluting the global environment). Modules can export values that may be imported and used by other modules.
Web pages load modules by including a script
tag with the type="module"
attribute.
<!-- load a script as a module -->
<script type="module" src="path/to/module.js"></script>
cd path/to/project
npx live-server .
where index.html is!
dot to serve entire folder
When an HTML page is opened with the file:// protocol, JavaScript cannot access system files. You need to run a local web server instead to use the http:// protocol.
You can do this with the live-server package
Access the webpage at http://localhost:8080/index.html
Stop the server by using ctrl+c in the command shell.
It is "possible" to import external libraries and make them available in your script from JavaScript (not HTML)
const util = require('java-util');
node version of "import"
global to refer
to the library
module library name
import { ArrayList } from 'java-util'; //named import
module library name
import java.util.ArrayList;
module name
variable to import
variable to import
from java-util import ArrayList
export
variables, functions, and classes to be available for other modules to
import
.
/*** my-module.js ***/
export function foo() { return 'foo'; } //named export
export const bar = "bar"; //export a variable
//will not be available (a "private" function)
function baz() { return 'baz'; }
/*** index.js ***/
//example of named imports:
import {foo} from './my-module.js'; //single named import
import {foo, bar} from './my-module.js'; //multiple named import
foo() //=> 'foo'
console.log(bar) //=> 'bar'
relative path to file (start with ./)
.js extension is implied by default in Node
Use the as keyword to "alias" a value.
Use import * syntax to import all values from a module.
/*** my-module.js ***/
export function foo() { return 'foo'; } //"named" export
//provide an "alias" (consumer name) for value
export { bar as yourBar };
/*** index.js ***/
import { yourBar } from './my-module.js'; //import value by name
yourBar() //=> 'bar'
import { bar } from './my-module.js'; //error, no value `bar` exported
//provide "alias" for value when importing!
import {foo as myFoo} from './my-module.js';
myFoo(); //=> 'foo'
//import everything that was exported
//loads as a single object with values as properties
import * as theModule from './my-module.js';
theModule.foo(); //=> 'foo'
theModule.yourBar(); //=> 'bar'
Each module can have a single default export, which provides a shortcut when importing.
/*** my-module.js ***/
export default function sayHello() {
return 'Hello world!';
}
/*** index.js ***/
//default import can assign own alias without needing name!
//think: "import {default as greet} from './mymodule.js'"
import greet from './my-module.js';
greet(); //=> "Hello world!"
Be careful about whether an export is named or default!
External libraries especially are not consistent.
//DOM - element to show
const msgElem = document.createElement('h1');
msgElem.id = 'hello';
msgElem.classList.add('myClass');
msgElem.textContent = 'Hello World!';
//show the content in the web page
//(inside #root)
document.getElementById('root').appendChild(msgElem);
//React - element to show
const msgElem = React.createElement(
//html tag
'h1',
//object of attributes
{ id: 'hello', className: 'myClass' },
//content
'Hello World!'
);
//Create a "React root" out of the `#root` elemment
//then render the React element at that root
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(msgElem)
can't use "class" since a keyword
React can be used to create and render DOM elements.
React v18 (March 2022)
An XML syntax extension for the JavaScript language. You define React elements in a way that looks like HTML!
//JSX - element to show
const msgElem = <h1 id="hello" className="myclass">Hello World</h1>;
//Create a "React root" out of the `#root` elemment
//then render the React element at that root
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(msgElem)
JSX
JS
JSX
JSX
JS
JS
CSS
JPG
CSS
JS
CSS
JPG
JPG
combined
minimized
compressed
etc.
create-react-app is a command line application that generates scaffolding ("starter code") for a React website.
# EITHER create a new react app
npx create-react-app app-name --use-npm
# OR install dependencies for existing project
cd path/to/project
npm install
# run the server
npm start
Runs a script that starts a development server which will:
Use {} to include JavaScript expressions in the JSX. These expressions will be evaluated and inserted into the element's "HTML".
//Can include JavaScript expressions in React elements
const message = "Hello world!";
const element = <h1>{message}</h1>;
//Can include arbitrary expressions
const element = (
<p>
A leap year has {(365 + 1) * 24 * 60} minutes!
</p>
);
//Can use inline expressions in attributes
const imgUrl = 'path/to/my_picture.png';
const pic = <img src={imgUrl} alt="A picture" />;
replace with expression (value)
use parentheses for JSX on multiple lines
React elements
must be closed
//Slide 22
import './style.css';
//Slide 22
const msgElem = <h1 id="hello" className="myclass">Hello React</h1>;
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(msgElem);
<!-- style.css -->
h1 {
font-family:Helvetica, Arial, sans-serif
}
//inside index.js
const root = ReactDOM.createRoot(document.getElementById('root'));
const title = "Hello JSX as a String";
const header = (
<header className="jumbotron">
<h1>{title}</h1>
<p>{1+1}</p>
<p>"hello world".toUpperCase()</p>
<p>{"hello world".toUpperCase()}</p>
</header>
);
root.render(header);
When put in line breaks to make the JSX readable, you need to put the whole thing in () so that ';' aren't assumed and entered for you
const msgElem = (
<div>
<header className="bg-dark p-3">
<h1 id="hello" className="text-light"> Hi Folks</h1>
</header>
<main>
<p>This is a paragraph in my main section</p>
</main>
</div>
);
const msgElem = (
<header className="bg-dark p-3">
<h1 id="hello" className="text-light"> Hi Folks</h1>
</header>
<main>
<p>This is a paragraph in my main section</p>
</main>
);
React lets us describe the page in terms of UI components, instead of HTML elements.
React lets us describe the page in terms of UI components, instead of HTML elements.
In effect, we will create our own XML Elements!
<App>
<HomePage>
<Header />
<SearchBar />
<EmployeeList>
<EmployeeListItem person="James King" />
<EmployeeListItem person="Julie Taylor" />
<EmployeeListItem person="Eugene Lee" />
</EmployList>
</HomePage>
<EmployeePage>
<Header />
...
</EmployeePage>
</App>
We define components as functions that return the DOM elements to be rendered
//declare a function to define a component
function HelloMessage(props) {
//this function returns the elements (JSX)
//that make up the component
return (
<h1>Hello World!</h1>
);
}
//"call" function to create a new element value!
const msgElem = <HelloMessage />;
//show the content in the web page (inside #root)
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(msgElem)
what is rendered when
component is shown
our own HTML tags!
Capitalize!
Create a component (function) called HelloMessage
const root = ReactDOM.createRoot(document.getElementById('root'));
function HelloMessage() {
let message = "Hello Everyone!";
return <h1>{message}</h1>;
}
const instance = <HelloMessage />;
root.render(instance);
function HelloMessage(props) {
return <p>Hello World!</p>;
}
function GoodbyeMessage(props) {
return <p>See ya later!</p>;
}
function MessageList(props) {
return (
<div>
<HelloMessage /> {/* A HelloMessage component */}
<GoodbyeMessage /> {/* A GoodbyeMessage component */}
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(msgElem)
Components can render other components ("call" functions to create new elements), and mix those with regular DOM elements
comments in JSX
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
function HeaderComponent(props) {
return (
<header className={weatherClass}>
<h1>Intro To React Demo</h1>
</header>
);
}
function MainComponent(props) {
return (
<main>
<ul>
<li>Chicken</li>
<li>Meerkat</li>
<li>Ape</li>
</ul>
</main>
)
};
continued on next slide ...
function App(props) {
return (
<div>
<HeaderComponent />
<MainComponent />
</div>
)}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<App />
);
continued from previous slide
Components are usually defined in separate modules (files), and then imported by modules that need to use them.
/*** in App.js ***/
//import from other components; HelloMessage.js, Messages.js, etc
import { HelloMessage } from './Messages'
//declare a function component
export default function App(props) {
return (
<HelloMessage /> {/* render imported Component */}
)
}
/*** in index.js ***/
import App from './App' //default import
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />)
// within the app.js file
import React from 'react';
import {HeaderComponent} from './Header.js' //named import
import {MainComponent} from './Main.js' //named import
export default function App(props) {
return (
<div>
<HeaderComponent />
<MainComponent />
</div>
)
}
/*** index.js ***/
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './components/App.js' //default import
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<App />
);
// Within the components/Header.js
import React from 'react';
export function HeaderComponent(props) {
const isRainy = true;
let weatherClass = "";
if (isRainy) {
weatherClass = "rainy"
}
return (
<header className={weatherClass}>
<h1>Intro To React Demo</h1>
</header>
);
}
// within the components/Main.js
import React from 'react';
export function MainComponent(props) {
const myList = "Animals";
return (
<main>
<p>{myList + "!!!"}</p>
<ul>
<li>Chicken</li>
<li>Meerkat</li>
<li>Ape</li>
<li>Goldfish</li>
</ul>
</main>
)
};
props
)
//Passing a prop called `message` with value "Hello property"
const messageA = <MessageItem message="Hello property!" />;
//A component can accept multiple props
//This component takes in a `name` property as well as
//a `descriptor` property
const userInfo = <UserInfo name="Ethel" descriptor="Aardvark" />;
//Passing a value as a prop using an inline expression
const secret = "Shave and a haircut";
const messageB = <MessageItem message={secret} />;
We specify attributes for a component (called "props") when we instantiate a component by specifying the XML attributes (key-value).
Props are the "input parameters" into a component!
props
)
function MessageItem(props) {
const message = props.message; //access the prop
//can use prop for logic or processing
const messageUpper = message.toUpperCase();
return <li>{messageUpper}</li>; //render based on prop
}
ReactDOM.createRoot(document.getElementById('root'))
.render(<MessageItem message="Be quiet" />)
Inside the Component function definition, all the passed in props are passed in as a single argument object (conventionally called props). This object is the collection of all of the attributes/arguments.
ALL props stored in this object
props
)
//Pass an array as a prop!
const array = [1,2,3,4,5];
const suitcaseElem = <Suitcase luggageCombo={array} />;
//Pass a function as a prop (like a callback)!
function sayHello() {
console.log('Hello world!');
}
const greetingElem = <Greeting callback={sayHello} />;
Importantly, props can be any kind of variable! This includes arrays, objects and functions
function MessageList(props) {
//msgComponents will be an array of components!
const msgComponents = props.messages.map((msgStr) => {
const elem = <MessageItem message={msgStr} key={msgStr} />; //pass prop down!
return elem
}
return (
<ul>
{/* An array of components renders as siblings */}
{msgComponents}
</ul>
);
}
const messagesArray = ["Hello world", "No borders", "Go huskies!"];
ReactDOM.createRoot(document.getElementById('root'))
.render(<MessageList messages={messagesArray} />)
Props will often need to be "passed down" to child components. A common pattern is to map an array of prop values to an array of children components to render!
unique "id" for the element
Read/Review Ch 15: React
Problem Set 06 due Monday
Problem Set 07 due 11 days after that
This is another big one!
Get started early; the project draft2 is 2/28
Next time: More React -- working with Components