Exploring .map .filter ...spread in React
Tags: beginners, javascript, react, webdev
Published: 2022-03-07 22:42:51

## Methods
As I'm progressing through my study of React, I learned that we often use arrays of objects. From importing list to creating our own, I realized that I needed to brush up on the .map() .filter() and ...spread array methods, and learn how to implement them properly in React. First we need understand the difference between these three methods, then we can learn to implement them.

Before I implement any array methods I ask myself what I want the end result to be. 
- Do I want to add elements to my array? I might want to use the spread operator.
- Do I want to delete elements in my array? The filter operator might be the way to go.
- Do I want to change an element in my array? The map operator could help make that happen.


## The Spread Operator
```javascript
...Spread
```
The spread operator is a part of ES6 and is just used by React. It creates a copy of an existing array and "spreads" the elements, and adds them and any new elements and returns a new array. When using it, your return will be a new array with more elements than your original. The spread operator is nondestructive. Meaning after all manipulations are done, your original array will still be the same as before. You can also use the spread operator to nondestructively replace certain information in your array.

For my examples I will be using the following array of objects:
```javascript
const users = [
    {
        id: 1,
        firstName: "Marie",
        lastName: "Curie",
        level: "Expert"
    },
    {
        id: 2,
        firstName: "Robert",
        lastName: "Oppenheimer",
        level: "Expert"
    },
    {
        id: 3,
        firstName: "Student",
        lastName: "Studentson",
        level: "Beginner"
    }
]
```

The following code shows and example of how the spread operator can be used.

```javascript
const newUser = [
  {
    id: 4,
    firstName: "Thomas",
    lastName: "Eddison",
    level: "Proficient"
  }
]

const allUsers = [...users, newUser]
```

A new constant called newUser was declared. Then another new constant called allUsers was created to document a new array with all the users inside of it. If we return the array it will show all the users, new and original, in one array. When applying this array operator in React, it works the same way. You can add it in both the jsx and javascript syntax portions of your code. 

```javascript
function ourFunction(){
    const [accounts, setAccounts] = useState([])

    function addUser(person) {
        if(!accounts.includes(person)){
            setAccounts([...users, person])
        }
    }

    return(
        <DisplayUsers onAddClick={addUser}/>
    )
}
```
In this example we are creating a new array using setAccounts and adding the new user to it through the spread operator. The spread operator works in the same way as it did in the example above, but in react, it can be harder to see what is being done behind the scenes due to syntax. We are creating a new array that contains the original array of users and adding a new user to it ('person', in this case, is a prop that contains the new user information). Once that is added we are returning a new array of users that will be assigned to setAccounts. 

##The Map Operator
```javascript
.map()
```
The map operator requires a callback function and a current element value to work. It takes every element in the array and "maps" it to something else. In our example above, we have an array called "Users", if we wanted to take each user and manipulate it separately, we would need to break the array into separate, usable pieces of data. To make this happen we use the map operator.

```javascript
 function UserDetails() {
      const oneUser = users.map(userObj => {
          <UserCard 
             firstName={userObj.firstName}
             lastName={userObj.lastName}
             level={userObj.level}
          />
})
  return (
    <div>
       {UserDetails}
    </div>
  )
}
```
The map operator has taken each user, and created a separate element for each user and then passed the deconstructed props into the UserCard component. There is some React syntax happening here that I won't be getting into in this blog. But, the map operator has manipulated our existing array of users and was able to return us each user in turn so we can manipulate each one separately. 
Since map is a nondestructive method, we need to state a new variable, to which we will assign our new array. Then we use the .map operator on our current element value: users. Inside the map operator we need to use a callback. In this callback we are declaring a new variable called userObj and using it to pass and deconstruct props into our userCard component. Now, when our user card component wants to create a separate user card for each user, it will take our mapped array and pull the information for each user separately, and repeat the process until there are no more users left.


##The Filter Operator
```javascript
.filter()
```
The filter operator checks each item against condition. If it's true it puts item back in array, if false it won't put them in the array. Similarly to the spread and map operators, the filter method is also a function of JavaScript, we aren't using React to filter. It is also a nondestructive way to manipulate arrays. We are going to use the filter method to return an array of users that are at "Expert" level.

```javascript
<div>
  {users.filter(user => user.level === 'Expert').map(filteredUser => (
    <li>
      {filteredUser.firstName}
    </li>
  ))}
</div>
```
In the example above, our filter checks which users return return true and a new array is created containing only those values. 
We apply the filter to our array called users and inside the filter operator we have a callback. In the callback we declare a variable called user and check if the user level, which we call on using dot notation, is equal to the "Expert" level. If our users satisfies our condition it is returned and the map operator is called on to return the users that satisfy our conditions. Another callback function inside our map operator returns a new array of first names that have passed our test. If none of the elements in our array pass the test, filter will return an empty array. The filter function will not work on an empty array.

The complete code for our filter operator is below.
```javascript
import React from 'react'

const users = [
    {
        id: 1,
        firstName: "Marie",
        lastName: "Curie",
        level: "Expert"
    },
    {
        id: 2,
        firstName: "Robert",
        lastName: "Oppenheimer",
        level: "Expert"
    },
    {
        id: 3,
        firstName: "Student",
        lastName: "Studentson",
        level: "Beginner"
    }
]

function UserDetails() {
  return (
  <div>
      {users.filter(user => user.level === 'Expert').map(filteredUser => (
      <li>
        {filteredUser.firstName}
     </li>
     ))}
  </div>
  )
}

export default UserDetails
```

##Final Thoughts

What I learned through my reading and investigating, is that the three array operators I focus on in this blog are actually used in JavaScript and are not different React operators or syntax. You can use them in vanilla Javascript and react in the same way. You can add react syntax and methods to make things easier and write less code, but the spread, map and filter operators will perform the same actions and work the same way in both scenarios.

---
##Sources

[Spread](https://www.techiediaries.com/react-spread-operator-props-setstate/)
[Spread](https://www.geeksforgeeks.org/what-is-the-meaning-of-spread-operator-in-reactjs/)
[Spread](https://medium.com/@pojotorshemi/uses-of-spread-operator-in-javascript-react-f5f456186e63)
[Spread](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax)
[Spread](https://www.w3schools.com/react/react_es6_spread.asp)
[Map Video](https://www.youtube.com/watch?v=G3BS3sh3D8Q)
[Map](https://www.w3schools.com/jsref/jsref_map.asp)
[Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
[Filter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
[Filter](https://www.w3schools.com/jsref/jsref_filter.asp)