📝 Notes for Learning React #5
-
😀 Contents are about Conditional Rendering & Froms in React
-
🚨 It is written only for myself (It may have no reference value) -
🔗 Source code in my GitHub
📚 Conditional Rendering
👇🏻 Multiple Returns - Basics
It is just a conditional returns example
import React, { useState, useEffect } from 'react';
const url = 'https://api.github.com/users/QuincyLarson';
const MultipleReturns = () => {
const [isLoading, setIsLoading] = useState(true);
if (isLoading) {
return <h2>Loading...</h2>;
}
return <h2>multiple returns</h2>;
};
export default MultipleReturns;
👇🏻 Multiple Returns - Fetching Example
🌻 Note
Response.json()Returns Value: ⬇️A Promise that resolves to a JavaScript object. This object could be anything that can be represented by JSON — an object, an array, a string, a number...
import React, { useState, useEffect } from 'react';
const url = 'https://api.github.com/users/QuincyLarson';
const MultipleReturns = () => {
const [isLoading, setIsLoading] = useState(true);
const [isError, setIsError] = useState(false);
const [user, setUser] = useState('default user');
// Fetching data
// Using `then` without `async/await`
useEffect(() => {
fetch(url)
.then(resp => resp.json())
.then(user => {
const { login } = user;
setUser(login);
setIsLoading(false);
})
.catch(err => console.log(err));
}, []);
if (isLoading) {
return (
<div>
<h2>Loading...</h2>
</div>
);
}
if (isError) {
return (
<div>
<h2>Error...</h2>
</div>
);
}
return <h2>{user}</h2>;
};
export default MultipleReturns;
👇🏻 Short Circuit
It's not about React, but all about JavaScript
import React, { useState } from 'react';
// short-circuit evaluation
// ternary operator
const ShortCircuit = () => {
const [text, setText] = useState('');
const firstValue = text || 'hello world';
const secondValue = text && 'hello world';
return (
<>
{/* <h1>{firstValue}</h1>
<h1>Value: {secondValue}</h1> */}
{/* ❌ SHOULD USE EXPRESSION: if () {console.log("hello world!")} */}
<h1>{text || 'Lucas Law'}</h1>
{/* 📝 We can use `&&` to display or hide the elements or components */}
{text && <h1>Hello World</h1>}
</>
);
};
export default ShortCircuit;
👇🏻 Show and Hide a component
import React, { useState, useEffect } from 'react';
const ShowHide = () => {
const [show, setShow] = useState(false);
return (
<>
<button className="btn" onClick={() => setShow(!show)}>
show/hide
</button>
{show && <Item />}
</>
);
};
const Item = () => {
const [size, setSize] = useState(window.innerWidth);
const checkSize = () => {
setSize(window.innerWidth);
};
useEffect(() => {
window.addEventListener('resize', checkSize);
// cleanup function
return () => {
window.removeEventListener('resize', checkSize);
};
}, []);
return (
<div style={{ marginTop: '2rem' }}>
<h1>window</h1>
<h2>size: {size} px</h2>
</div>
);
};
export default ShowHide;
📚 Forms
👇🏻 Form - Basics
🌻 Note
Why do we use
<label>❓Typically, you will place every
<input>inside a<label>tag. This tells the browser that this label is associated with that input. When the user clicks the label, the browser will automatically focus the input. It’s also essential for accessibility: a screen reader will announce the label caption when the user focuses the associated input.
import React, { useState } from 'react';
const ControlledInputs = () => {
const handleSubmit = e => {
// 🟢 `e.preventDefault()` We can see the 'hello world' without refreshing the page.
e.preventDefault();
console.log('Hello World');
};
return (
<>
<article>
<form className="form" onSubmit={handleSubmit}>
<div className="form-control">
<label htmlFor="firstName">Name : </label>
<input type="text" id="firstName" name="firstName" />
</div>
<div className="form-control">
<label htmlFor="email">Email : </label>
<input type="text" id="email" name="email" />
</div>
<button type="submit" onClick={handleSubmit}>
add person
</button>
</form>
</article>
</>
);
};
export default ControlledInputs;
👇🏻 Controlled - Inputs
💡 Some thoughts
Let's think about how to connect the inputs in to our state?
I mean how to access data of inputs that user input?
🌻 Note
👇🏻 The old style way for the 'key' to be asigned by 'values'
const person = { firstName: firstName, email: email };👇🏻 The ES6 way for the 'key' to be asigned by 'values' (shorthands way)
const person = { firstName, email };
Now here is the example that we connect the inputs into state:
import React, { useState } from 'react';
// JS
// const input = document.getElementById('myText');
// const inputValue = input.value
// React
// value, onChange
const ControlledInputs = () => {
const [firstName, setFirstName] = useState('');
const [email, setEmail] = useState('');
const handleSubmit = e => {
e.preventDefault();
console.log('Hello World');
};
return (
<>
<article>
<form className="form" onSubmit={handleSubmit}>
<div className="form-control">
<label htmlFor="firstName">Name : </label>
<input
type="text"
id="firstName"
name="firstName"
value={firstName}
onChange={e => setFirstName(e.target.value)}
/>
</div>
<div className="form-control">
<label htmlFor="email">Email : </label>
<input type="text" id="email" name="email" value={email} />
</div>
<button type="submit" onClick={handleSubmit}>
add person
</button>
</form>
</article>
</>
);
};
export default ControlledInputs;
👇🏻 Add Items to the List
import React, { useState } from 'react';
// JS
// const input = document.getElementById('myText');
// const inputValue = input.value
// React
// value, onChange
const ControlledInputs = () => {
const [firstName, setFirstName] = useState('');
const [email, setEmail] = useState('');
const [people, setPeople] = useState([]);
const handleSubmit = e => {
e.preventDefault();
// If the values are not empty, we will add a person to the `people` state
if (firstName && email) {
// 🟢 CHEAT: Setting date as id
const person = { id: new Date().getTime().toString(), firstName, email };
// WOW I like this coding style ⬇️
setPeople(people => {
return [...people, person];
});
// We will reset the inputs after setting people
setFirstName('');
setEmail('');
} else {
console.log('empty values');
}
};
return (
<>
<article>
<form className="form" onSubmit={handleSubmit}>
<div className="form-control">
<label htmlFor="firstName">Name : </label>
<input
type="text"
id="firstName"
name="firstName"
value={firstName}
onChange={e => setFirstName(e.target.value)}
/>
</div>
<div className="form-control">
<label htmlFor="email">Email : </label>
<input
type="text"
id="email"
name="email"
value={email}
onChange={e => setEmail(e.target.value)}
/>
</div>
<button type="submit" onClick={handleSubmit}>
add person
</button>
</form>
{people.map(person => {
const { id, firstName, email } = person;
return (
<div className="item" key={id}>
<h4>{firstName}</h4>
<p>{email}</p>
</div>
);
})}
</article>
</>
);
};
export default ControlledInputs;
👇🏻 Multiple - Inputs
What to do in this part?
- We are refactoring the code.
- As above of the code, there 4
statedefinitions in our component. (too many) - We want to keep code dry and cleaned.
import React, { useState } from 'react';
// JS
// const input = document.getElementById('myText');
// const inputValue = input.value
// React
// value, onChange
// dynamic object keys
const ControlledInputs = () => {
const [person, setPerson] = useState({ firstName: '', email: '', age: '' });
const [people, setPeople] = useState([]);
// Change the value(firstName, email, age) of state while user is changing the inputs
const handleChange = e => {
const name = e.target.name; // Set the `name` in `<input>` as the 'key'
const value = e.target.value; // Set the `value` in `<input>` as the 'value'
// https://react.dev/learn/updating-objects-in-state
// 👉🏻 Using spread syntax to keep the previous values for all other fields.
setPerson({
...person, // Copy other fields
[name]: value, // Dynamically set the specific key
});
};
const handleSubmit = e => {
e.preventDefault();
// Fields are not empty!
if (person.firstName && person.email && person.age) {
const newPerson = { ...person, id: new Date().getTime().toString() };
setPeople([...people, newPerson]);
// And remember to set `person` as an empty state
setPerson({ firstName: '', email: '', age: '' });
}
};
return (
<>
<article>
<form className="form">
<div className="form-control">
<label htmlFor="firstName">Name : </label>
<input
type="text"
id="firstName"
name="firstName"
value={person.firstName}
onChange={handleChange}
/>
</div>
<div className="form-control">
<label htmlFor="email">Email : </label>
<input
type="email"
id="email"
name="email"
value={person.email}
onChange={handleChange}
/>
</div>
<div className="form-control">
<label htmlFor="age">Age : </label>
<input
type="text"
id="age"
name="age"
value={person.age}
onChange={handleChange}
/>
</div>
<button type="submit" onClick={handleSubmit}>
add person
</button>
</form>
{people.map((person, index) => {
const { id, firstName, email, age } = person;
return (
<div className="item" key={id}>
<h4>{firstName}</h4>
<p>{age}</p>
<p>{email}</p>
</div>
);
})}
</article>
</>
);
};
export default ControlledInputs;
✉️ Contact me anyway if I get somethings wrong here.