Hooks
useState
Take your solution from the Components / JSX
section and add following behaviour:
Solution
import React from 'react'
function Address(props) {
return (
<>
<p>{props.address.street}</p>
<p>
{props.address.city} {props.address.zipcode}
</p>
<p>{props.address.country}</p>
</>
)
}
function Person(props) {
const [showAddress, setShowAddress] = React.useState(false)
return (
<div>
<img width="250" alt="" src={props.person.profilePicture} />
<h1>
{props.person.firstName} {props.person.lastName}
</h1>
<p>Phone: {props.person.phone}</p>
<p>
Email: <a href={props.person.email}>{props.person.email}</a>
</p>
<a href={props.person.website}>{props.person.website}</a>
<br />
<br />
<button onClick={() => setShowAddress(!showAddress)}>
{showAddress ? 'Hide' : 'Show'} Address
</button>
{showAddress ? <Address address={props.person.address} /> : null}
</div>
)
}
function App() {
const users = [
{
firstName: 'John',
lastName: 'Smith',
email: 'john@example.com',
profilePicture:
'https://images.pexels.com/photos/6206980/pexels-photo-6206980.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1',
phone: '+1 (123) 456-7890',
address: {
street: '9062 Mertz Plains Apt. 623',
buildingNumber: '410',
city: 'Boganside',
zipcode: '71562',
country: 'Estonia',
},
website: 'http://www.johnsmith.com',
},
{
firstName: 'Raegan',
lastName: 'Haley',
email: 'ustroman@hotmail.com',
profilePicture:
'https://images.pexels.com/photos/733872/pexels-photo-733872.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1',
phone: '+5089956276536',
address: {
street: '2922 Retha Plaza',
city: 'Lake Gail',
zipcode: '26859-4338',
country: 'Mozambique',
},
website: 'http://zboncak.biz',
},
]
return (
<>
<Person person={users[0]} />
<br />
<Person person={users[1]} />
</>
)
}
export default App
useMemo
The calculate function runs on every click of the button and slows the application. Can you improve the code by using useMemo?
Example
function Component() {
const [state, setState] = React.useState(0);
const calculate = () => {
let a = 0;
for (let i = 0; i < 10_000; i++) {
for (let j = 0; j < 10_000; j++) {
a += i + j;
}
}
return a;
};
return (
<div>
<button onClick={() => setState(state + 1)}>Add +1</button>
<pre>{state}</pre>
{calculate()}
</div>
);
}
export default function App() {
return <Component />;
}
useCallback
Woops, what is happening here?
If we click the first CustomButton component, the second CustomButton component gets rerendered.
Let's fix this by using useCallback
.
Example
import React from "react";
function CustomButton({ onClick, children }) {
React.useEffect(() => {
console.log(`button ${children} is rerendered!`);
}, [onClick]);
return <button onClick={onClick}>{children}</button>;
}
function Wrapper() {
const [isCheckedFirst, setIsCheckedFirst] = React.useState(false);
const [isCheckedSecond, setIsCheckedSecond] = React.useState(false);
return (
<>
<CustomButton onClick={() => setIsCheckedFirst(!isCheckedFirst)}>
First isChecked
</CustomButton>
<p>{isCheckedFirst ? "First is checked" : "First is not checked"}</p>
<CustomButton onClick={() => setIsCheckedSecond(!isCheckedSecond)}>
Second isChecked
</CustomButton>
<p>{isCheckedSecond ? "Second is checked" : "Second is not checked"}</p>
</>
);
}