Basics - Samples
Samples - Events, Props, Children
import React, { useState, useEffect } from 'react';
export function SampleHero({ children, ...props }) {
return (
<div className="px-4 py-5 my-5 text-center">
<p className="h1">{props.title}</p>
<div className="col-lg-6 mx-auto">
<p className="lead mb-4">
{props.body}
</p>
<div className="svtack gap-2 col-md-4">
{children}
</div>
</div>
</div>
);
}
// component expects param:onClick
export function SampleButton({ children, classes, ...props }) {
return (
<button className={`btn btn-primary ${classes}`} onClick={props.onClick}>
{children}
</button>
);
}
export function SampleBadge({ children }) {
return (
<span className="badge bg-secondary">{children}</span>
);
}
export function HooksComp1() {
const [count, setCount] = useState(0);
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
// Update the document title using the browser API
document.title = `You clicked ${count} times`;
// localStorage.setItem('count', count);
});
return (
<div className="px-4 py-5 my-5 text-center">
<p className="h1">You clicked <span className="badge bg-secondary">{count} times</span></p>
<div className="col-lg-6 mx-auto">
<p className="lead mb-4">
Quickly design and customize responsive mobile-first sites with
Bootstrap, the world’s most popular front-end open source toolkit,
featuring Sass variables and mixins, responsive grid system,
extensive prebuilt components, and powerful JavaScript plugins.
</p>
<div className="d-grid gap-2 d-sm-flex justify-content-sm-center">
<button className="btn btn-primary" onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
</div>
</div>
);
}
function useCountHolder(curCount) {
const [count, setCount] = useState(curCount);
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
// Update the document title using the browser API
document.title = `You clicked ${count} times`;
// localStorage.setItem('count', count);
});
return [count, setCount];
}
export function HooksComp2() {
const [count, setCount] = useCountHolder(10);
function handleClickCount() {
setCount(count + 1)
}
return (
<div className="px-4 py-5 my-5 text-center">
<p className="h1">You clicked <span className="badge bg-secondary">{count} times</span></p>
<div className="col-lg-6 mx-auto">
<p className="lead mb-4">
Quickly design and customize responsive mobile-first sites with
Bootstrap, the world’s most popular front-end open source toolkit,
featuring Sass variables and mixins, responsive grid system,
extensive prebuilt components, and powerful JavaScript plugins.
</p>
<div className="d-grid gap-2 d-sm-flex justify-content-sm-center">
<button className="btn btn-primary" onClick={handleClickCount}>
Click me
</button>
</div>
</div>
</div>
);
}
export function HooksComp3() {
const [count, setCount] = useState(10);
function handleClickCount() {
setCount(count + 1)
}
return (
<SampleHero title="Events Demo" body="Sample stage management across parent child">
<p className="h1"><SampleBadge>Clicked {count} times</SampleBadge></p>
<p className="h1"><SampleBadge>Clicked*2 {count*2} times</SampleBadge></p>
<p className="h1"><SampleBadge>Clicked*4 {count*4} times</SampleBadge></p>
<SampleButton onClick={handleClickCount}>Click Me</SampleButton></SampleHero>
);
}
Multiple Children
Children is a Normal Prop Too Here’s a cool thing about the way React handles children: the nested elements get assigned to the children prop, but it’s not a magical special prop. You can assign it just like any other. Behold. Ref
// This code...
<Button children={<span>Click Me</span>} />
// Is equivalent to this code...
<Button>
<span>Click Me</span>
</Button>
<Layout
left={<Sidebar/>}
top={<NavBar/>}
center={<Content/>}
/>
Another Sample - useEffect and useState
- Demonstrates data fetch
- Promise.all
- use of prevState with useState
// source: https://stackoverflow.com/questions/68210088/how-to-stop-multiple-re-renders-from-doing-multiple-api-calls-useeffect
const key = process.env.REACT_APP_API_KEY
const fetchCity = async city => {
const { data } = await axios.get(
https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${key},
)
return { description: data.weather[0].description, icon: data.weather[0].icon, temp: data.main.temp, city: data.name, country: data.sys.country, id: data.id, } }
function App() { const [cities, setCities] = useState([]) const [activeWeather, setActiveWeather] = useState([])
useEffect(() => { const fetchCities = async () => { const citiesData = await Promise.all( ['Ottawa', 'Toronto', 'Vancouver'].map(fetchCity), )
setCities(prevState => prevState.concat(citiesData))
}
fetchCities()
}, []) }
## CSS Style Sheets
```js
// ref: https://www.w3schools.com/react/react_css_styling.asp
// local custom style
// [1] inline
// note: camelCased Property Names
// Use backgroundColor instead of background-color:
const Header = () => {
return (
<>
<h1 style={{backgroundColor: "lightblue"}}>Hello Style!</h1>
<p>Add a little style!</p>
</>
);
}
// [2] as variable
const Header = () => {
const myStyle = {
color: "white",
// note: camelCased Property Names
// Use backgroundColor instead of background-color:
backgroundColor: "DodgerBlue",
padding: "10px",
fontFamily: "Sans-Serif"
};
return (
<>
<h1 style={myStyle}>Hello Style!</h1>
<p>Add a little style!</p>
</>
);
}
// import module specific css
import styles from './my-style.module.css';
const Car = () => {
return <h1 className={styles.bigblue}>Hello Car!</h1>;
}
export default Car;
The CSS inside a module is available only for the component that imported it, and you do not have to worry about name conflicts.
import styles from './my-style.module.css';
const Car = () => {
return <h1 className={styles.bigblue}>Hello Car!</h1>;
}
export default Car;
Handling - Form Submits and Input Fields
// https://www.w3schools.com/react/react_forms.asp
import { useState } from 'react';
import ReactDOM from 'react-dom/client';
function MyForm() {
const [inputs, setInputs] = useState({});
const handleChange = (event) => {
const name = event.target.name;
const value = event.target.value;
setInputs(values => ({...values, [name]: value}))
}
const handleSubmit = (event) => {
event.preventDefault();
alert(inputs);
}
return (
<form onSubmit={handleSubmit}>
<label>Enter your name:
<input
type="text"
name="username"
value={inputs.username || ""}
onChange={handleChange}
/>
</label>
<label>Enter your age:
<input
type="number"
name="age"
value={inputs.age || ""}
onChange={handleChange}
/>
</label>
<input type="submit" />
</form>
)
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<MyForm />);
Form Validation Options
Check out this or similar. Good start -> React Hook Form