[Udemy] React 기본 - 일기장 만들기(5) DELETE

productuidev·2022년 4월 25일
1

React Study

목록 보기
23/52
post-thumbnail
post-custom-banner

React 기본 (Project)

Udemy - 한입크기로 잘라 먹는 리액트


📌 일기장 만들기 (5) - DELETE

☑️ DELETE

  • 리스트에 있는 데이터 삭제
  • DiaryItem에 삭제 버튼을 만들고, 기능 구현을 통해 배열의 데이터를 삭제하는 방법

☑️ 삭제하기 버튼 추가

  • 삭제하기 버튼 추가 (onClick 이벤트 핸들러)

src/DiaryItem.js : 고유 id 콘솔 출력

        <button onClick={() => {
          console.log(id); 
        }}>삭제하기</button>

☑️ onDetele 함수 추가

  • 이전시간처럼 똑같이 App 컴포넌트가 가진 data state를 바꾸기 위해 삭제하기 버튼을 누를 경우, 해당 배열을 뺀 배열로 data state가 업데이트 되어야 함.
    (예: 4개 배열 중 삭제 하면 3개 배열로 App 컴포넌트 상태가 업데이트되어야 한다는 뜻)

src/App.js

 	// targetId : 어떤 id를 갖고있는 요소를 지우길 원하는지 매개변수로 전달 받음
  const onDelete = (targetId) => {
    console.log(`${targetId}가 삭제되었습니다`);
  };

☑️ DiaryItem이 onDelete 함수를 호출할 수 있어야 함

  • 부모인 DiaryList 컴포넌트에 Props로 onDelete 함수를 내려준다.

src/App.js

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

☑️ DiaryList에서 onDelete 함수를 내려받음 Prop으로 전달

  • DiaryItem의 부모인 DiaryList에 onDelete 함수를 Prop으로 내려준 다음 DiaryList에서는 부모로부터 받은 onDelete 함수를 DiaryItem한테 Prop으로 내려준다 (두 다리를 거쳐 감)

Props Drilling
: App 컴포넌트 > DiaryList 컴포넌트 > DiaryList는 사용하진 않지만 DiaryItem에게 내려준다

src/DiaryList.js

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

☑️ DiaryItem에서 Prop으로 전달받음

src/DiaryItem.js

const DiaryItem = ({
  onDelete,
  id,
  author,
  content,
  emotion,
  created_date
  }) => {
    return (
      <div className="DiaryItem">
        <div className="info">
          <span className="author_info">
            | 작성자 : {author} | 감정점수 : {emotion} |
          </span>
          <br />
          <span className="date">{new Date(created_date).toLocaleString()}</span>
        </div>
        <div className="content">{content}</div>
        {/* 삭제하기 버튼 추가, 대화박스 alert 추가 */}
        <button onClick={() => {
          if (window.confirm(`${id}번째 일기를 정말 삭제하시겠습니까?`)) {
            onDelete(id); // 현재 id 
          }
        }}>삭제하기</button>
      </div>
    );
};

export default DiaryItem;

☑️ 삭제 후 렌더링할 화면

  • 배열 요소를 제외한 남은 배열은 setData 함수에 전달하여 data state의 배열을 바꿔주면 된다
  • 새로운 DiaryList에서 it.id가 삭제한 targetId가 아닌 것으로 필터링(filter 내장함수 사용)
  • setData에 전달하고 나면 삭제된 배열을 제외한 남은 배열로 새 배열을 만들어서 상태 변화 업데이트(리렌더링)

src/App.js

  const onDelete = (targetId) => {
    console.log(`${targetId}가 삭제되었습니다`);
    const newDiaryList = data.filter((it) => it.id !== targetId);
    //console.log(newDiaryList);
    setData(newDiaryList);
  };

📖 참고자료

  • 프로퍼티 내리꽂기(Props Drilling)
  • 왜 Props Drilling 을 피해야 하는지 알아본다.
  • Prop drilling 해결을 위해 context를 사용하기 전에 구조를 생각해보자.
    자체적인 상태관리가 필요없고, 단순히 레이아웃인 컴포넌트라면 prop을 직접적으로 넘기면 된다. 너무 많은 사람들이 prop-drilling에서 context로 섣불리 넘어가버리려고 한다. 더 많은 컴포넌트를 염두에 두고, 구성요소를 구조화 한다면 더 유지 보수가 쉬워지고, 성능및 관리 문제가 줄어들 것이다.
  • redux
    리액트에서 어떤 프롭스를 아래,아래,아래,아래,아래,아래에 있는 하위 컴포넌트에서 써야할 때가 있는데 그때마다 최하위 뎁스까지 연속해서 프롭스를 전달해야한다. 이것을 프롭스 드릴링 이라고 한다. 그 숨막히는 프롭스 드릴링 노가다(?)는 같은 작업을 반복한다는 점에서도 문제가 있지만, 유지보수가 깔끔치 못하다는 점이 크다고 볼 수 있다. 이를 해결하기 위해 리덕스를 사용한다. 전역변수 같은 스토어라는 걸 하나 두고 상태를 관리하겠다는 것.
  • Context API
    Context API는 리액트 프로젝트 내 전역 상태 관리에 사용되는 리액트 훅, 전역 상태를 관리하지 않으면 컴포넌트마다 State를 하위로 분배해야 하는 프롭스 드릴링(Props Drilling)이 필수라, 프로젝트 관리에 어려움이 생김
profile
필요한 내용을 공부하고 저장합니다.
post-custom-banner

0개의 댓글