127.0.0.1 welcomes you.
This is the third in the series, if you haven't checked the previous lessons, check out Understanding Components and Props, otherwise, let's goooo.
Table of Contents
- The Map() Function
- Rendering Arrays
- The key prop
- Handling Click Events
- Handling Form Events
- Passing arguments to event handlers
The Map() Function
map() is a JavaScript function that specifically works on arrays. It does a specified manipulation or rather applies the specified function to each of the items of an array and returns a new array.
To break it down even further, suppose you have a list of numbers [1,2,3,4,5] and you want to get the squares of these items in a new array.
What happens is that, you will get each item, multiply it by itself, and return the result into a new array.
But instead of doing all this manually, map() helps you do all that. If we have const squares = [1,2,3,4,5], let's see how to map that.
const squares = [1, 2, 3, 4, 5]
//get squares of items into result
var result = squares.map((item)=> item * item)
//print result
console.log(result)
So, what exactly happens?
squares.map() goes through each individual element in the array.
We see the signature map((item)). Item is just an identifier, or a variable that is enclosed or local to within that function. This means that it can't be accessed outside this map function.
There are other overloads to the map function e.g map((item, index)). This signature takes 2 arguments where the item is the current item and index is the position of this item in the array. It is worth noting that, map must have at least an argument, which will reference the item. The other arguments are optional.
(item)=> item * item is an anonymous arrow function. This syntax will return a result item*item in a new array in the position of the current item.
So at the end, result will have [1,4,9,16,25]
Map is not only used in such manipulations as above, it can be used to also render JSX for every item. If you have a JSX that should take each value of the array and render it, this can be done as below:
First, let's create a component that takes an argument
export const Hello = ({name})=> {
return(<p>Hello, {name}</p> )
}
Then, we map each of the values to this element, creating a new element for each item.
const names = ["Silas", "Jeff", "Britt", "Tiffany"]
names.map(it=>{
return <Hello name={it}/>
})
This will create four elements with dynamic name fields matching the fields in the names. And that is how you can use map to dynamically render items.
Rendering Arrays in JSX
We have already seen this in the above, especially with arrays.
Let's look at rendering arrays with objects.
The same concept follows:
const users = [ { age: 21, name: "Alice" }, { age: 32, name: "Brian" }, { age: 23, name: "Carol" } ];
names.map(it=>{
return <Hello name={it.name} age={it.age}/>
})
And the component be:
export const Hello = ({name, age})=> {
return(<p>Hello, {name}. You are {age} years old!</p> )
}
This should give an output like:
Hello, Alice. You are 21 years old!
Hello, Brian. You are 32 years old!
Hello, Carol. You are 23 years old!
Rendering objects is much more common in real applications because data from APIs usually comes as arrays of objects.
The Key Prop
The key refers to a property that uniquely identifies an item/record when it comes to rendering a list with the map function.
React always expects a key prop when rendering a list. This will be linted in the browser console if you don't supply one.
const users = [ { id: 1, name: "Alice" }, { id: 2, name: "Brian" }, { id: 3, name: "Carol" } ];
function App() {
return (
<ul> {users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul> );
}
Keys are essential in the sense that, since react keeps updating UI when state changes, it needs a way to keep track of:
- What items changed
- What item was removed
- What item was added.
These keys help React to efficiently compare the previous and current list, minimizing unnecessary updates
Good keys use values that are unique and predictable, e.g user.id, user.email.
Avoid using indexes as the keys since these indexes change when items are inserted or removed.
Handling Click Events
In React, click events are handled almost the same way as in HTML, but the only difference being the use of camelCase for the event names.
Instead of onclick, React offers onClick, and instead of onclick='handleSubmit()', we have onClick={handleSubmit}.
In this case handleSubmit is a function. Sometimes you might need to do onClick={()=>handleSubmit()}
use onClick={handleSubmit} when your function doesn't need arguments
const submit = (e) => {
e.preventDefault();
console.log("Form submitted!");
};
<button onClick={submit}>Submit</button>
use onClick={()=>handleSubmit} when your function needs arguments and/or you need to specify how your function gets called
const submit = (id, type) => {
console.log(`Submitting ID: ${id} with type: ${type}`)
};
<button onClick={() => submit(42, 'admin')}>Submit</button>
Handling Form Events
The most common form events are onChange and onSubmit.
Every time the user types in the form, the onChange function is called.
function App() {
function handleChange(event) {
console.log(event.target.value)e;
}
return (
<input
type="text"
onChange={handleChange}
/>
);
}
onSubmit is called every time the submit button or action is called. This often triggers the form to reset and clear out fields.
function App() {
function handleSubmit(event) {
event.preventDefault();
alert("Form submitted!");
}
return (
<form onSubmit={handleSubmit}>
<button>Submit</button>
</form>
);
}
To remedy this, React stops this by the event.preventDefault() This stops the auto-reset of the form on submission allowing you to handle the form without reloading the page.
It is worth noting that event is auto passed into the function as in(event)=>handleSubmit(event)
Passing Arguments to Event Handlers
Sometimes you want to pass an argument into a function. In this case, <button onClick={deleteUser}> wont suffice. You will therefore need to pass the item into the arrow function as: <button onClick={()=>deleteUser(userId)}>
This will then call deleteUser function with the argument userId
Example:
function App() {
function greet(name) {
alert(`Hello ${name}`);
}
return (
<button onClick={() => greet("Alice")}>
Greet
</button>
);
}
The above program, when the button is clicked, it will display Hello Alice
But, if you wrote <button onClick={greet("Alice")}, the function would execute immediately during rendering instead of waiting for the click.
In other cases, if you did that and opened the browser console, you might see 99+ errors on console, mostly followed by your machine breathing heavily as it tries to remain afloat!!
SO... Don't kill your machine!!😁
If you've come this far, you're doing great. Keep it going.
Key Takeaways
- Use
map()to transform arrays into JSX elements. - JSX can directly render arrays returned by
map(). - Always provide a unique
keyprop when rendering lists. - React event handlers use camelCase names like
onClickandonSubmit. - Form events such as
onChangeandonSubmitlet React respond to user input. - Use arrow functions when you need to pass arguments to event handlers.
- Combining list rendering with event handling is a common pattern for building interactive React applications.
Play around, learn, explore. Let's meet in the next one. 🖖👋
Top comments (0)