ECE366 - Lesson 7
React
Instructor: Professor Hong
## Create React App
- Install nodejs - [https://nodejs.org/](https://nodejs.org/)
- nodejs on WSL - [https://learn.microsoft.com/en-us/windows/dev-environment/javascript/nodejs-on-wsl](https://learn.microsoft.com/en-us/windows/dev-environment/javascript/nodejs-on-wsl)
- Remove old version of node:
```
sudo apt-get purge --auto-remove nodejs
```
- ```node -v``` - to check node version
- ```npm -v``` - check npm version
- ```npx create-react-app rps```
- ```npm start```
## Important Parts
- package.json - dependencies - react, react-dom, react-scripts
- src/index.js - entry point of the application, main JS file
- renders App
- React.StrictMode - additional checks
- public/index.html - similar to index.html w/ all your JSX injected
```
npm install
npm start
```
## Javascript Destructuring
Allows you to get specific elements from an argument/props
```
function App({ myVariable }) {
return (
{myVariable
);
}
```
- Also Array destructuring allows you to get certain elements from an array
## Changing States with useState
App.js
```
import "./App.css";
import { useState } from "react";
function App() {
const [emotion, setEmotion] = useState("happy");
return (
<div className="App">
<h1>Current emotion is {emotion}</h1>
<button onClick={() => setEmotion("sad")}>
Sad
</button>
<button
onClick={() => setEmotion("excited")}
>
Excited
</button>
</div>
);
}
export default App;
```
## Side Effects with useEffect
```
import "./App.css";
import { useState, useEffect } from "react";
function App() {
const [emotion, setEmotion] = useState("happy");
const [secondary, setSecondary] =
useState("tired");
useEffect(() => {
console.log(`It's ${emotion} around here!`);
}, [emotion]);
useEffect(() => {
console.log(`It's ${secondary} around here!`);
}, [secondary]);
return (
<div className="App">
<h1>Current emotion is {emotion}</h1>
<button onClick={() => setEmotion("sad")}>
Sad
</button>
<button
onClick={() => setEmotion("excited")}
>
Excited
</button>
<h2>
Current secondary emotion is {secondary}.
</h2>
<button
onClick={() => setSecondary("grateful")}
>
Grateful
</button>
</div>
);
}
export default App;
```
- dependencyArray is the 2nd argument for useEffect
- No argument makes it called everytime
- Empty array makes it called once
## Fetching Data from Service
fetch is built into the browser to make an HTTP request to get data
```
import "./App.css";
import { useState, useEffect } from "react";
function App() {
const [data, setData] = useState(null);
useEffect(() => {
fetch(
`http://localhost:8080/api/users`
)
.then((response) => response.json())
.then(setData);
}, []);
if (data)
return (
<pre>{JSON.stringify(data, null, 2)}</pre>
);
return <h1>Data</h1>;
}
export default App;
```
## Update CORS in Spring Boot server
WebserviceController.java
```
@CrossOrigin
@GetMapping("/users")
```
Can also put it after @RestController above the class definition
## React Forms
useRef - a hook that is going to reach out to some UI element and get its value, doesn't re-render
```
import "./App.css";
import { useRef } from "react";
function App() {
const txtTitle = useRef();
const hexColor = useRef();
const submit = (e) => {
e.preventDefault();
const title = txtTitle.current.value;
const color = hexColor.current.value;
alert(`${title}, ${color}`);
txtTitle.current.value = "";
hexColor.current.value = "";
};
return (
<form onSubmit={submit}>
<input
ref={txtTitle}
type="text"
placeholder="color title..."
/>
<input ref={hexColor} type="color" />
<button>ADD</button>
</form>
);
}
export default App;
```
## React Forms with useState
re-renders at the end
```
import "./App.css";
import { useState } from "react";
function App() {
const [title, setTitle] = useState("");
const [color, setColor] = useState("#000000");
const submit = (e) => {
e.preventDefault();
alert(`${title}, ${color}`);
setTitle("");
setColor("#000000");
};
return (
<form onSubmit={submit}>
<input
value={title}
onChange={(event) =>
setTitle(event.target.value)
}
type="text"
placeholder="color title..."
/>
<input
value={color}
type="color"
onChange={(event) =>
setColor(event.target.value)
}
/>
<button>ADD</button>
</form>
);
}
export default App;
```
## Form Libraries
- formik
- react hook forms
## React Router
To install:
```
npm install react-router-dom
```
## Configuring the Router
App.js
```
import "./App.css";
function Home() {
return (
<div>
<h1>My Website</h1>
</div>
);
}
export function About() {
return (
<div>
<h1>About Us</h1>
</div>
);
}
export function Contact() {
return (
<div>
<h1>Contact Us</h1>
</div>
);
}
export function App() {
return <Home />;
}
```
## Configuring the Router
index.js
```
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { App, About, Contact } from "./App";
import {
BrowserRouter,
Routes,
Route
} from "react-router-dom";
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<BrowserRouter>
<Routes>
<Route path="/" element={<App />} />
<Route path="/about" element={<About />} />
<Route
path="/contact"
element={<Contact />}
/>
</Routes>
</BrowserRouter>,
);
```
## Adding Links to the Router
App.js
```
import "./App.css";
import { Link } from "react-router-dom";
function Home() {
return (
<div>
<nav>
<Link to="/about">About</Link>
<Link to="/contact">Contact</Link>
</nav>
<h1>My Website</h1>
</div>
);
}
export function About() {
return (
<div>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/contact">Contact</Link>
</nav>
<h1>About Us</h1>
</div>
);
}
export function Contact() {
return (
<div>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/contact">Contact</Link>
</nav>
<h1>Contact Us</h1>
</div>
);
}
export function App() {
return <Home />;
}
```
## RPS Game Logic
- Add server side logic
- Add UI to communicate with server