Built at: 2024-10-16T09:55:25.150Z Skip to content

part1c

Component state, event handlers

start from new example
// App.js
const Hello = (props) => {
return (
<div>
<p>
Hello {props.name}, you are {props.age} years old
</p>
</div>
);
};
const App = () => {
const name = "Peter";
const age = 10;
return (
<div>
<h1>Greetings</h1>
<Hello name="Maya" age={26 + 10} />
<Hello name={name} age={age} />
</div>
);
};
Component helper functions
const Hello = (props) => {
const bornYear = () => {
const yearNow = new Date().getFullYear();
return yearNow - props.age;
};
return (
<div>
<p>
Hello {props.name}, you are {props.age} years old
</p>
<p>So you were probably born in {bornYear()}</p>
</div>
);
};
one line function
const bornYear = () => new Date().getFullYear() - props.age;
destructuring
const Hello = (props) => {
const name = props.name;
const age = props.age;
// or: const { name, age } = props
const bornYear = () => new Date().getFullYear() - age;
return (
<div>
<p>
Hello {name}, you are {age} years old
</p>
<p>So you were probably born in {bornYear()}</p>
</div>
);
};
or
const Hello = ({ name, age }) => {

page re-rendering

start from new example
// App.js
const App = (props) => {
const { counter } = props;
return <div>{counter}</div>;
};
export default App;
index.js
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
let counter = 1;
ReactDOM.createRoot(document.getElementById("root")).render(
<App counter={counter} />
);

check the page.

refresh in setInterval
// index.js
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
let counter = 1;
const root = ReactDOM.createRoot(document.getElementById("root"));
const refresh = () => {
root.render(<App counter={counter} />);
};
setInterval(() => {
refresh();
counter += 1;
}, 1000);

The page now have a number increased every second.

use state

index.js now reset as below
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
App.js changes to:
import { useState } from "react";
const App = () => {
const [counter, setCounter] = useState(0);
setTimeout(() => setCounter(counter + 1), 1000);
return <div>{counter}</div>;
};
export default App;
console.log to check the status
console.log("rendering...", counter);

event handling

register an event handler
const App = () => {
const [counter, setCounter] = useState(0);
const handleClick = () => {
console.log("clicked");
};
return (
<div>
<div>{counter}</div>
<button onClick={handleClick}>plus</button>
</div>
);
};
refactor to setCounter
const App = () => {
const [counter, setCounter] = useState(0);
return (
<div>
<div>{counter}</div>
<button onClick={() => setCounter(counter + 1)}>plus</button>
</div>
);
};

Event handler is a function.
<button onClick={setCounter(counter + 1)}> doesn’t work
<button onClick={() => setCounter(counter + 1)}> is correct

add more handlers
// App.js
const App = () => {
const [counter, setCounter] = useState(0);
const increaseByOne = () => setCounter(counter + 1);
const decreaseByOne = () => setCounter(counter - 1);
const setToZero = () => setCounter(0);
return (
<div>
<div>{counter}</div>
<button onClick={increaseByOne}>plus</button>
<button onClick={setToZero}>zero</button>
<button onClick={decreaseByOne}>minus</button>
</div>
);
};

passing state to child components by props

App.js
import { useState } from "react";
const Display = (props) => {
return <div>{props.counter}</div>;
};
const Button = (props) => {
return <button onClick={props.onClick}>{props.text}</button>;
};
const App = () => {
const [counter, setCounter] = useState(0);
const increaseByOne = () => setCounter(counter + 1);
const decreaseByOne = () => setCounter(counter - 1);
const setToZero = () => setCounter(0);
return (
<div>
<Display counter={counter} />
<Button onClick={increaseByOne} text="plus" />
<Button onClick={setToZero} text="zero" />
<Button onClick={decreaseByOne} text="minus" />
</div>
);
};
export default App;

Changes in state(which set in useState) cause rerendering

refactoring the components by restructuring
const Display = ({ counter }) => <div>{counter}</div>;
const Button = ({ onSmash, text }) => <button onClick={onSmash}>{text}</button>;