map(),filter()

Mintaek·2022년 8월 13일

JavaScript

목록 보기
6/8
post-thumbnail

🔎 Map()

map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환한다.

const arr = [1, 2, 3, 4, 5]

이런 배열이 있다.

배열 안에 있는 모든 요소를 제곱하여 새로운 배열을 만들고 싶다면 어떻게 해야 할까?

바로 map() 메서드를 사용하면 된다.

const arr = [1, 2, 3, 4, 5];

const mapArr = arr.map(num => num * num);

console.log(arr);
// > Array [1, 2, 3, 4, 5]

console.log(mapArr);
// > Array [1, 4, 9, 16, 25]

map() 메서드 안에 들어가는 내용은 callback함수이다.

배열 arr에 있는 요소(num)들에 함수를 실행하고 나온 값(num * num)을 저장하여 새로운 배열(mapArr)로 만든다.

map() 활용하기
배열의 요소들을 화면에 그리도록 map() 을 활용해 볼 것이다.

App.js
import "./App.css";
import Test01 from "./07/Test01";

function App() {
  return (
    <div className='App'>
      <Test01 />
    </div>
  );
}

export default App;

Test01 함수 컴포넌트

import React from "react";

export default function Test01() {
  const todoList = [
    { taskName: "방 청소", finished: false },
    { taskName: "화장실 청소", finished: true },
  ];

  // map() 함수
  const todos = todoList.map((todo) => <div>{todo.taskName}</div>);
  return (
    <>
      <label>TO DO</label>
      {todos}
    </>
  );
}

Test01 클래스 컴포넌트

import React, { Component } from "react";

class Test01 extends Component {
  render() {
    const todoList = [
      { taskName: "방 청소", finished: false },
      { taskName: "화장실 청소", finished: true },
    ];

    // map() 함수
    const todos = todoList.map((todo) => <div>{todo.taskName}</div>);
  return (
    <>
      <label>TO DO</label>
      {todos}
    </>
    );
  }
}

export default Test01;

객체를 요소로 가진 todoList 라는 배열을 만들었다.

taskName 을 화면에 그리고 싶어, map() 함수를 사용했다.

const todos = todoList.map((todo) =>

{todo.taskName}
);

todo의 taskName만 가져와 todos 라는 이름을 가진 컴포넌트가 map() 함수를 돌면서 출력될 것이다.

만약 map()이 없었더라면?!
배열에서 일일이 꺼내기

Test02 함수 컴포넌트

import React from "react";

export default function Test02() {
  const todoList = [
    { taskName: "방 청소", finished: false },
    { taskName: "화장실 청소", finished: true },
  ];
  
  return (
    <>
      <label>TO DO</label>
      <div>{todoList[0].taskName}</div>
      <div>{todoList[1].taskName}</div>
    </>
  );
}

Test02 클래스 컴포넌트

import React, { Component } from "react";

class Test02 extends Component {
  render() {
    const todoList = [
      { taskName: "방 청소", finished: false },
      { taskName: "화장실 청소", finished: true },
    ];

  return (
    <>
      <label>TO DO</label>
      <div>{todoList[0].taskName}</div>
      <div>{todoList[1].taskName}</div>
    </>
    );
  }
}

export default Test02;

이렇게 일일이 todoList 배열의 요소들을 선택하여 꺼내주어야 한다.

위처럼 배열의 요소가 적다면 일일이 꺼내는 게 어려운 일은 아니겠지만,
만약 배열의 요소의 개수가 사용자에 의해 변한다거나 점점 많아질수록 일일이 꺼내기 어려워지며, 코드도 불필요하게 길어지게 될 것이다.

map()과 key

Warning: Each child in a list should have a unique "key" prop

map() 함수를 사용하면 콘솔창에 위와 같은 에러가 뜰 것이다.

대충 해석해보니 리스트에 유니크한 키 값이 없다는 것 같다.

React는 key Prop을 사용하여 컴포넌트와 DOM 요소 간의 관계를 생성한다.
이렇게 생성된 관계를 이용하여 컴포넌트 리렌더링 여부를 결정하는데,
불필요한 리렌더링을 방지하기 위해서 자식 컴포넌트마다 독립적인 key 값을 주어야 한다.

key 값 주기

Test01 함수 컴포넌트

import React from "react";

export default function Test01() {
  const todoList = [
    { taskName: "방 청소", finished: false },
    { taskName: "화장실 청소", finished: true },
  ];

  return (
    <>
      {todoList.map((todo, i) => (
        <div key={`tl-${i}`}>{todo.taskName}</div>
      ))}
    </>
  );
}

Test01 클래스 컴포넌트

import React, { Component } from "react";

class Test01 extends Component {
  render() {
    const todoList = [
      { taskName: "방 청소", finished: false },
      { taskName: "화장실 청소", finished: true },
    ];

  return (
    <>
      {todoList.map((todo, i) => (
        <div key={`tl-${i}`}>{todo.taskName}</div>
      ))}
    </>
    );
  }
}

export default Test01;

map() 을 사용하여 각 컴포넌트에 배열의 index로 고유한 key 값 을 주었다.

그러나, 배열의 index 를 key 값 으로 주는 것은 지양해야 한다.

배열의 요소들의 순서가 바뀌는 경우에는 배열 요소의 index 도 바뀌고, 컴포넌트마다 고유한 key 값 도 같이 바뀐다.
이러면 리액트는 리렌더링 해야하는 컴포넌트를 헷갈려 다른 컴포넌트를 리렌더링할 수도 있다.

key 값 은 전역적으로 고유할 필요는 없고, 형제 사이에서 고유해야 한다.

Test01 함수 컴포넌트

import React from "react";

export default function Test01() {
  const todoList = [
    { taskName: "방 청소", finished: false },
    { taskName: "화장실 청소", finished: true },
  ];

  return (
    <>
      {todoList.map((todo) => (
        <div key={todo.taskName}>{todo.taskName}</div>
      ))}
    </>
  );
}
Test01 클래스 컴포넌트
import React, { Component } from "react";

class Test01 extends Component {
  render() {
    const todoList = [
      { taskName: "방 청소", finished: false },
      { taskName: "화장실 청소", finished: true },
    ];

  return (
    <>
      {todoList.map((todo) => (
        <div key={todo.taskName}>{todo.taskName}</div>
      ))}
    </>
    );
  }
}

export default Test01;

그래서 한 번 taskName 을 key 값 으로 주었다.

콘솔에 있던 오류 창이 사라졌다!

🔎 Filter()

filter() 메서드는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환한다.

  • filter() 활용하기
const todoList = [
  { taskName: "방 청소", finished: false },
  { taskName: "화장실 청소", finished: true },
];

위에서 만들었던 todoList 배열이다.

filter() 메서드를 활용하여 finished 가 false 인 것만 화면에 그리도록 해보려고 한다.

Test01 함수 컴포넌트

import React from "react";

export default function Test01() {
  const todoList = [
    { taskName: "방 청소", finished: false },
    { taskName: "화장실 청소", finished: true },
  ];

  return (
     <>
      {todoList
        .filter((todo) => todo.finished === false)
        .map((todo, i) => (
          <div key={todo.taskName}>{todo.taskName}</div>
        ))}
    </>
  );
}

Test01 클래스 컴포넌트

import React, { Component } from "react";

class Test01 extends Component {
  render() {
    const todoList = [
      { taskName: "방 청소", finished: false },
      { taskName: "화장실 청소", finished: true },
    ];

  return (
    <>
      {todoList
        .filter((todo) => todo.finished === false)
        .map((todo, i) => (
          <div key={todo.taskName}>{todo.taskName}</div>
        ))}
    </>
    );
  }
}

export default Test01;
profile
Slow and Steady Wins the Race

0개의 댓글