<info 340/>

React Apps

Joel Ross
Autumn 2026 (A)

View of the Day

Today we're going to start converting projects into React, getting AI to help us!

  • Setting up a React Project

  • Identifying Components

  • Converting HTML to React!

  • Data-Driven Components

  • Intro to Interactivity (if time)

Test and check your work in the browser

 

Only run Jest when the problem is finished and functional

Any questions?

# change directories to your project
cd path/to/project-repo

# create a react app in _this_ folder
# note the period to create in current folder!
# When prompted, choose to 'Ignore existing files and continue'
npm create vite@latest . -- --template react

Details in the Project Draft 2 Assignment:

  1. Move current project files into a draft-1 folder
  2. Create the Vite template





     
  3. Cleanup the starter code
  4. Move draft-1 folder back
  5. Commit and push!

Set Up React

Vite Dev Server

Vite provides a development server which will:

  • Automatically transpile React code into pure JavaScript
  • Manage module dependencies, including external libraries
  • Show build and syntax errors in the console
  • Automatically reload the page (replaces live-server)!
# Make sure you are in the project directory
cd path/to/project

# Install dependencies for existing project (installs vite)
npm install

# Run the development server script
npm run dev -- --host

some Windows machines

Identifying Components

It's useful identify potential components by hand before relying on the AI; that way you will know what it is doing!

 

Look for "parts", "boxes" and repeated elements--those are likely Components!

Let's make a chat app!

Converting HTML

Let's try it! On one person's computer, ask Copilot to build one page or component out of the HTML

  • Start by giving it context for the project
  • Tell it precisely what you want it to do, in "plain language"
  • List any limits or restrictions

 

"The draft-1 folder contains an HTML & CSS version of a project. I am incrementally converting this into a Vite+React project in the current folder.
Create a new ____ Component using the HTML from the ____ file, putting that component in the current src folder.

Do not add any interactive functionality, just convert the content

Structure the content into sub-components if needed."

                        ... and other details?

What did you get?

After it builds, discuss what code it created!

  • What component(s) did it make? Where?
  • How are those components structured? Anything look different from what we've seen so far?
  • Does the page look correct when rendered?

 

Commit and push the changes and we can discuss!

React Components

We define components as functions that return the DOM elements to be rendered

//declare a function to define a component -- this is like a class
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!

Properties (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

Subcomponents

AI systems will often try to make "one big component" for a page, which can make it hard to work with.

 

Try having it break up a big component into smaller pieces!

Props and Composition

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

React Style Guidelines

More Converting

Now that you've gone through an example, try having each team member convert a page. Talk through what you get as it happens. Remember to commit and push your changes!

Data

React Components are data-driven Views. They are intended to convert a set of data (props) into rendered content on the screen. This means to determine what you see, you're going to need to know what kind of data your app will be using!

Data

  1. Discuss with your team: what is the "main" data one of your components will need?
  2. What is the schema for that data? Can you make a sample record in JSON?
  3. Ask CoPilot to produce more sample data for you!
     
  4. import the data into your project, and pass it into your components!

Conditional Rendering

You can use control logic (if statements) to specify whether or not a component should be rendered.

function ConditionalPanel(props) {
  //assign element to show to variable
  let thingToRender = null; //null element will not render
  if(conditionOne){ //based on props or state
    thingToRender = <OptionA />
  } else if(conditionTwo) {
    thingToRender = <OptionB />
  } else if(conditionThree) {
    return null; //show nothing!
  }
    
  //keep return statement as simple as possible!
  return (<div>{thingToRender}</div>);
}
function ConditionPanel(props) {
  //can use inline expressions via shortcutting. Not recommended
  return (
    <div>
      {conditionOne == true && <OptionA />}
    </div>
  )
}

Interactivity

React Events

We add user interaction in React the same way as with the DOM: by listening for events and executing callback functions when they occur. 

function MyButton(props) {
  //A function that will be called when clicked 
  //The name is conventional, but arbitrary.
  //The callback will be passed the DOM event as usual
  const handleClick = function(event) {
    console.log("clicky clicky");
  }

  //make a button with an `onClick` attribute!
  //this "registers" the listener and sets the callback
  return <button onClick={handleClick}>Click me!</button>;
}

special React prop

can only put listeners on HTML
elements, not Components!

function MyButton(props) {
  //A function that will be called when clicked 
  //The name is conventional, but arbitrary.
  //The callback will be passed the DOM event as usual
  const handleClick = (event) => {
    console.log("clicky clicky");
  }

  //make a button with an `onClick` attribute!
  //this "registers" the listener and sets the callback
  return <button onClick={handleClick}>Click me!</button>;
}

DOM Interactivity

//The current "state"
const state = {
  data: [ {}, {}, {} ],
  ...
}

  
//define presentation - lots of these kinds of functions
function renderData() {
  //render all the data
  //...
}

//define user interaction
button.addEventListener('click', function() {
  //MODIFY THE STATE
  state.data[i] = ...; 

  //CLEAR OLD VIEW AND RE-RENDER CONTENT
  document.querySelector('#main').innerHTML = '';
  renderData(); //RE-RENDER CONTENT    
})

changeable data lives out here

1. modify the state data

2. re-render the view

2. re-render the view

On button click, do 2 things:

In addition to the props, React components can also track their internal state. This keeps track of information about the Component that may change due to user interaction.

React State

State is reserved only for interactivity, that is, data that changes over time

Some examples of state data:

  1. The sorted order of child components
  2. Timers or dynamic content
  3. Which model data are shown!

You add state to a component by using a state hook. The hook defines a "state variable" which will retain its value across Component function calls, as well as a function to update that variable.

Using State Hooks

//import the state hook function `useState()` to define state
import React, { useState } from 'react';

function CountingButton(props) {
  const [count, setCount] = useState(0);

  
  
 
  const handleClick = (event) => {
    setCount(count+1); //update the state to be a new value
                       //and RE-RENDER the Component!
  }

  return (
      <button onClick={handleClick}>Clicked {count} times</button>
  );
}

state variable

update function

initial value for variable

Naming Conventions Matter!

In order to write correct React (that can be understood
and debugged by you and others), you need to follow the naming conventions:

  • The argument to a Component function is called props (with an s)
     
  • A "state-setter" function for state variable foo is called setFoo (replacing "foo" with the state variable name)

Changing State

React state is changed asynchronously (for speed). Calling a "state-setter" function (when ready) and automatically re-render the Component (by calling the function again).

function CountingButton(props) {
  const [count, setCount] = useState(3) //initial value of 3

  const handleClick = (event) => {
    setCount(4); //change `count` to 4 AND re-render!
    console.log(count); //will output "3"; 
                        //state has not changed yet!
  }  
 
  console.log(count); //will have "current" value of state
                      //3 first render, 4 after clicking
  
  return (
    <button onClick={handleClick}>Clicked {count} times</button>
  );    
}

Debugging State

Because state changes are asynchronous, you can only "see" them after the component has re-rendered. Use console logs at the "rendering" step to debug 

function CountingButton(props) {
  const [count, setCount] = useState(3) //initial value of 3

  console.log("DEBUG: count", count); //debug! variable here, 
                                      //after re-render
  
  
  const handleClick = (event) => {
    setCount(count + 1); //incremenet count AND re-render!
    //do not debug variable here!
  }  
  
  return (
    <button onClick={handleClick}>Clicked {count} times</button>
  );    
}

Multiple State Variables

Components can (and often do) contain multiple state variables.

//Example from React documentation
function ExampleWithManyStates(props) {
  //Declare multiple state variables!
  const [age, setAge] = useState(42);
  const [fruit, setFruit] = useState('banana');
  const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
  
  //...  
}

state variable is an array of objects!

Props vs State

props are for information that doesn’t change from the Component’s perspective, including “initial” data. state is for information that will change, usually due to user interaction (see React FAQ).

  1. Is the value passed in from a parent via props? If so, it probably isn’t state.
     
  2. Does the value remain unchanged over time? If so, it definitely isn’t state.
     
  3. Can you compute it based on any other state or props in your component? If so, it definitely isn’t state.

props are for information that doesn’t change from the Component’s perspective, including “initial” data. state is for information that will change, usually due to user interaction (see React FAQ).

Action Items!

Action Items!

  • Complete task list for Week 7 (all items) 

  • Read/review: Chapter 15-16

  • Problem Set 07 due next week

    • You can do problem-a and 3/4 of problem-b

    • Start now so you have time​​

Wednesday is a holiday!

  • No class
  • Take a look at the textbook and videos!
     

​Next: Making React Interactive!

info340au26a-react-apps

By Joel Ross

info340au26a-react-apps

  • 111