프론트앤드/React

[포스코x코딩온] 웹개발자 입문 과정 8주차 | map & filter

영최 2023. 4. 26. 23:54
728x90

1.map()

 어떤 배열 -> 새로운 배열로 만들고자 할 때 map()함수를 사용한다.

 map()함수의 인자는 callback함수이다.

arr.map(callback(currentValue[, index[, array]])[, thisArg])

 이 콜백함수의 인자는

  • currentValue: 처리할 현재 요소
  • index: 현재 요소의 인덱스 - optional
  • array: map()을 호출한 배열 - optional

 으로 총 3가지의 인자를 가진다.

 thisArg 는 callback을 실행할 때 this로 사용되는 값이다.

 

 아래의 예시를 확인해보자

let numbers = [1, 4, 9];
let doubles = numbers.map((num) => {
  return num * 2;
});

 doubles의 출력은 [2, 8, 18] 이 된다.  위 코드에서는 콜백함수 인자를

 currentValue인 num만 사용해서 그 값의 두배를 값으로 지정한

 새로운 배열 doubles를 만들었다.

 

 이 map()함수를 사용하면 for문을 대신하여 반복문처럼 활용할 수 있다.

 

 이 map()을 리액트에서 사용할 때 주의할 점이 한가지 있다.

 바로 키값을 위 map()함수의 콜백함수 인자인 index값으로 지정하는 것을 

 리액트가 선호하지 않는다.

 

 이유는 index값으로 키값을 지정할 경우 만약 중간에 배열의 값이 사라질 경우에

 키값이 index값이므로 변동되기 때문이다.

 

 리액트는 업데이트 기존 소와 업데이트 요소를

 비교하는데 key사용하기때문에

 위 처럼 index값을 key값으로 지정하기 보다는

 state를 지정해서 고유 id키값으로 지정해줄 것을 권장한다.

 

 그래서 index값을 키값으로 지정하면 리액트에서 아래같은 에러문구가 발생한다.

 each child in a list should have a unique "key" prop.

 

 

 

2.filter()

 filter() 메서드는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 

 새로운 배열로 반환한다.

    arr.filter(callback(element[, index[, array]])[, thisArg])

 filter()메소드도 마찬가지로 callback함수를 인자로 가진다. 

 이 callback함수는 true를 반환하면 요소를 유지하고, false를 반환하면 버리는 역할을 한다.

 

 callback함수는 아래와 같이 세가지 인자를 받는다.

  • element: 처리할 현재 요소
  • index: 현재 요소의 인덱스 - optional
  • array: filter를 호출한 배열 - optional

 thisArg 는 callback을 실행할 때 this로 사용되는 값이다.

 

 예시

const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter(word => word.length > 6);

console.log(result);
//출력 결과 >> : Array ["exuberant", "destruction", "present"]

 

3.실습 예제

 

import { useState } from "react";
const Alphabet = () => {
  // alphabet state: 리스트에 대한 상태
  const [alphabet, setAlphabet] = useState([
    { id: 1, alpha: "a" },
    { id: 2, alpha: "p" },
    { id: 3, alpha: "p" },
    { id: 4, alpha: "l" },
    { id: 5, alpha: "e" },
  ]);
  //inputAlpha state: input에 넣는 값에 대한 상태
  const [inputAlpha, setInputAlpha] = useState("");
  console.log(alphabet);

  const addAlpha = () => {
    // concat(): 인자로 주어진 값을 기존 배열에 합쳐서 새로운 배열을 반환
    if (inputAlpha.trim().length === 0) return; //8. 공백일 경우 추가 안되도록함

    const newAlphabet = alphabet.concat({
      id: alphabet.length + 1,
      alpha: inputAlpha,
    });

    // console.log(newAlphabet);
    setAlphabet(newAlphabet); //2.리스트 상태 업데이트
    setInputAlpha(""); //3.추가 클릭시 인풋창 초기화
  };

  //5. 삭제기능 구현 -> filter (배열 모든 원소 순회해서 삭제요소 빼고 모든 요소 반환)
  //filter(): 콜백함수의 테스트를 통과하는 모든 요소를 모아서 "세로운 배열" 반환
  //true 요소 유지, false 요소 버림
  //=> alphabet state에서 매개변수로 받아오는 id와 배열 각 원소의 id가 같은 경우 빼고
  //   나머지를 모두 새로운 배열에 저장
  const deleteAlpha = (id) => {
    const newAlpha = alphabet.filter((obj) => obj.id !== id); //다르면 반환
    setAlphabet(newAlpha); //상태 업데이트
  };
  const activeEnter = (e) => {
    console.log(e.key); //어떤 키를 눌렀는지 확인 가능
    if (e.key === "Enter")
      //7.엔터쳐도 추가되도록, 한문장일 경우 if문 중괄호 생략 가능
      addAlpha();
  };

  return (
    <>
      <input
        type="text"
        value={inputAlpha}
        onChange={(e) => {
          setInputAlpha(e.target.value); //1.입력한 값으로 inputAlpha 값 변화
        }}
        onKeyDown={(e) => activeEnter(e)} //6.엔터쳐도 추가되도록
      />
      <button onClick={addAlpha}>추가</button> {/*0. addAlpha함수 생성*/}
      <ol>
        {alphabet.map((obj) => (
          <li key={obj.id} onDoubleClick={() => deleteAlpha(obj.id)}>
            {obj.alpha}
          </li> //4. 더블클릭시 이벤트 생성
        ))}
      </ol>
    </>
  );
};
실행 영상

 

728x90