[React] filter( )로 배열 삭제하기 (feat.일기장)

Hyun·2022년 1월 5일
1

React

목록 보기
9/22
post-thumbnail

💡filter( )란?

  • filter() 메서드는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열을 반환합니다.
  • 원하는 값들을 필터링 하는 것
  • filter()는 배열 내 각 요소에 대해 한 번 제공된 callback 함수를 호출해, callback이 true로 강제하는 값을 반환하는 모든 값이 있는 새로운 배열을 생성합니다. callback은 할당된 값이 있는 배열의 인덱스에 대해서만 호출됩니다; 삭제됐거나 값이 할당된 적이 없는 인덱스에 대해서는 호출되지 않습니다. callback 테스트를 통과하지 못한 배열 요소는 그냥 건너뛰며 새로운 배열에 포함되지 않습니다.

구문

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

  • callback = 각 요소를 시험할 함수
    true를 반환하면 요소를 유지하고, false를 반환하면 버립니다. 다음 세 가지 매개변수를 받습니다.
    • element = 처리할 현재 요소
    • index(Optional) = 처리할 현재 요소의 인덱스
    • array(Optional) = filter를 호출한 배열
  • thisArg(Optional) = callback을 실행할 때 this로 사용하는 값

반환 값

테스트를 통과한 요소로 이루어진 새로운 배열. 어떤 요소도 테스트를 통과하지 못했으면 빈 배열을 반환합니다.

💡props drilling이란?

  • 리액트의 컴포넌트 트리에서 상위에서 하위로 데이터를 전달하기 위해서 필요한 과정을 의미합니다.

일기리스트를 추가하는것을 했는데, 이제 일기를 삭제하고싶다.
일기리스트에 삭제버튼을 생성하고 누르면 리스트(배열)이 삭제되는 방법을 배우겠다.

🎯코딩 순서 정리

  1. DiaryItem.js에 가서 삭제버튼을 생성한다.
  2. App.js컴포넌트에 가서 data를 수정해야한다
    (삭제하기버튼을 클릭한 리스트만 빼고 filter( )로 새로운 리스트를 업데이트 시켜줘야한다)
    (onRemove함수를 만들고 매개변수로 지우길원하는=삭제버튼을 누른 id를 받는다)
  3. DiaryItem삭제버튼이 App의 onRemove함수를 호출할 수 있어야한다.
    (=App부모가 DiaryItem자식에게 props로 onRemove함수를 내려줌)
  4. App부모가 DiaryList자식에게도 props로 onRemove함수를 내려줌
    ➡️ DiaryList는 onRemove를 사용하지는 않지만 내려줘야한다. 이를 props drilling이라고한다.(자세한건 나중에..일단 정의만 알아두도록하자)
  5. 삭제하기버튼을 누르면 '삭제하시겠습니까?confirm을 이용하여 알림뜨도록
    (*confirm은 대화박스가 alert처럼 나오고 확인,취소 선택이 가능한 알림창)

📖예제

1. DiaryItem.js

const DiaryItem = ({onRemove, author, content, created_date, emotion, id}) => {
    return <div className="DiaryItem">
        <div className="info">
            <span>
                작 성 자 : {author} | 감 정 점 수 : {emotion}
            </span>
            <br />
            <span className="date">
                시 간 : {new Date(created_date).toLocaleString()}
            </span>
            <div className="content">
                내 용 : {content}
            </div>

            //삭제버튼
            <button onClick={() => {
                if (window.confirm(`${id+1}번째 일기를 삭제하시겠습니까?`)){
                    onRemove(id);
                }
            }}>삭 제 하 기
            </button>
        </div>
    </div>
};

export default DiaryItem;

<코드설명>

1)const DiaryItem = ({onRemove, author, content, created_date, emotion, id})

= App.js부모컴퍼런트로부터 받은 onRemove props를 추가해준다.

2) <button onClick={() => {
if (window.confirm(${id+1}번째 일기를 삭제하시겠습니까?)){
onRemove(id);
}
}}>삭 제 하 기
</button>

= 삭제버튼을 생성하고, onClick이벤트로 confirm창을 띄워 확인버튼을 누를 경우 onRemove함수에 해당id를 전달하여 삭제를 실행한다.
(*이때, confirm창에 있는것은 사용자가 볼 화면으로, 0번째보단 1번째로 인식해서 id+1로 보여주는것이 맞다고 생각한다.)

2.App.js

import { useRef, useState } from 'react';
import './App.css';
import DiaryEditor from "./DiaryEditor";
import DiaryList from "./DiaryList"

const App = () => {
  const [data,setData] = useState([]);
  const dataId = useRef(0);
  const onCreate = (author,content,emotion) => {
    const created_date = new Date().getTime();
    const newItem = {
      author,
      content,
      emotion,
      created_date,
      id: dataId.current
    };
    dataId.current += 1;
    setData([newItem, ...data])
  };
  
  //삭제함수
  const onRemove = (targetId) => {
    const newDiaryList = data.filter((it) => it.id !== targetId);
    setData(newDiaryList);
  }

  return (
    <div className="App">
      <DiaryEditor onCreate={onCreate} />
      <DiaryList onRemove={onRemove} diaryList={data} />
    </div>
  );
}

export default App;

<코드설명>

1) const onRemove = (targetId) => {
const newDiaryList = data.filter((it) => it.id !== targetId);
setData(newDiaryList);
}

= App.js부모컴퍼넌트에서 onRemove함수를 정의한다.
targetId는 DiaryItem.js자식컴퍼넌트에서 함수수행 id를 전달받는다
그후 newDiaryList를 targetId를 제외하고 필터하여 재정의하고 setData상태변화함수로 newDiaryList를 전달한다.

2) <DiaryList onRemove={onRemove} diaryList={data} />

=DiaryItem삭제버튼이 App의 onDelete함수를 호출할 수 있어야하므로 App부모가 DiaryItem자식에게 props로 onRemove함수를 내려줌

DiaryList.js

import DiaryItem from "./DiaryItem.js"

const DiaryList=({onRemove, diaryList}) => {
    return (
    <div className="DiaryList">
        <h2>일기리스트</h2>
        <h4>{diaryList.length}개의 일기가 있습니다.</h4>
        <div>
            {diaryList.map((it) => (
                <DiaryItem key={it.id} {...it} onRemove={onRemove}/>
            ))}
        </div>
    </div>
    );
};

export default DiaryList;

<코드설명>

1)const DiaryList=({onRemove, diaryList})

= App.js부모로부터 받은 onRemove props를 사용할것이므로 추가한다.

2)<DiaryItem key = {it.id} {...it} onRemove={onRemove}/>

= App부모가 DiaryList자식에게도 props로 onRemove함수를 내려줌
(➡️ DiaryList는 onRemove를 사용하지는 않지만 내려줘야한다. 이를 props drilling이라고한다.)


🎯한눈에 로직 정리


(made.hyun👩🏻‍💻)


일기장 화면


삭제하기 버튼이 뜬 화면

두번째 일기에 삭제하기 버튼을 클릭한 화면

두번째 일기가 삭제된 화면


🚀참고자료

prop-drilling
MDN-filter()
React강의-이정환강사

profile
FrontEnd Developer (with 구글신)

0개의 댓글