[할일리스트]삭제/ 완료 or 진행중 버튼추가 + 진행중만 보기

piper ·2024년 4월 3일
0

Project

목록 보기
10/15

목표: 현재 있는 카드컴포넌트에 삭제/완료 or 진행중 버튼을 추가 하고 진행중인 카드컴포넌트만 따로 보여주는 기능을 만든다.

<삭제>

과정:
1) 리듀서 툴킷 slice 에 삭제 액션을 추가한다.
(1)삭제 방법으로는 filter 메서드를 사용하였다. 주의할 점은 action.payload에 담아야 할 내용인데 item.id가 payload인 것을 기억해야한다. 나는 dispatch가 써져있는 컴포넌트에서 id만을 파라미터 즉 payload에 담아주었는데 왜냐면 그것으로 비교를 하고 id가 같지 않은 것만 필터링해서 다시 카드를 보여줄것이기 때문이다. 나는 그것을 잊고 console.log(action.payload)에 왜 전체 객체가 뜨지 않는지 의아해 했다.
(2) 이 과정이 더 중요하다고 볼 수 있었다. 왜냐면 실제로 삭제 기능이 작동되지 않았기 때문인데
이유는 state.todos가 proxy라는 값을 담고 있었다. 이러한 원인은 툴킷 기능에 자동으로 immer 기능이 포함되어있으면서 직접적으로 객체에 접근하는 것이 아니라 프록시라는 데이터를 사용하고 있기 때문이었다.
따라서 state.todos= 와 같이 그 안에 함수를 담아줘야만 했다. 하지만 아직 의문인건 add 버튼을 만들 때는 그렇게 하지 않고 직접 변경해줬는데 두번째 부터는 이렇게 해야만 한다는 점이다.

delete(state, action) {
      state.todos = state.todos.filter((item) => item.id !== action.payload);
    },

2) dispatch로 삭제 이벤트를 실행할 수 있게끔 전달해준다.

const clickDelete = (e) => {
    e.stopPropagation();
    dispatch(todoActions.delete(todo.id));
  };

<완료 or 진행중>

과정:
1) 리듀서 툴킷 slice에 완료인지 진행중인지 표시해주는 액션을 만든다.
state.todos 배열 안을 돌면서 item이라는 객체의 키 id의 값을 확인한다. 만약 클릭한 id와 같으면 done이라는 키의 값을 false에서 true로 바꿔준다. 이 때 사용한것은 스프레드 문법이다.

  status(state, action) {
      state.todos = state.todos.map((item) =>
        item.id === action.payload ? { ...item, done: !item.done } : item
      );
    },
  },
});

2) useDispatch로 액션을 전달해준다.

 const clickDone = (e) => {
    console.log("나클릭2");
    e.stopPropagation();
    dispatch(todoActions.status(todo.id));
  };

3) 여기서는 버튼을 done이 false면 in progress로 true면 done으로 보여지도록 만들어서 진행중인지 완료인지를 화면에 나타낼 수 있게 해주었다.

<p>{todo?.done ? "done" : "in progress"}</p>
        
<div>
    <button onClick={clickDelete}>Delete</button>
          {todo?.done ? (
            <button onClick={clickDone}>In progress</button>
          ) : (
            <button onClick={clickDone}>Done</button>
          )}
</div>

<진행중만 보기>

과정:
1) 먼저 mui에서 적절한 아이콘을 골랐다. 그리고 switch라는 컴포넌트에 만들어주었다. 여기에서부터 생각하는게 필요해졌다. 나는 이 switch 컴포넌트를 todoList의 차일드로 만들어주었는데 inProgress로 bar가 옮겨져 갔을 때 이러한 사항을 알려주고 그 사항을 전달받아서 화면에 sorting해주는 기능이 필요했다. 그러러면 두 가지를 현재의 컴포넌트에서 수정해야했다. (1) todoList에서 map으로 카드를 보여주는 것이 아닌 child인 switch 컴포넌트에서 map을 해야한다. (2) map을 하는 사항이 두가지가 있다. 모두보기와 진행중만 보기. 그렇다면 새로운 배열 안에 진행중만 따로 모아야하고, 화면에 다르게 그려주기 위해서는 state와 삼항연산자를 사용해서 두 가지 버전으로 그려줘야한다.

1)-(1)
모두 보여지는 list와 진행중만 보여지는 list (done===false)두가지를 만들었다.

 const recentList = useSelector((state) => state.addTask.todos);
  console.log(recentList);
  const inProgressList = recentList.filter((item) => item.done === false);
  console.log(inProgressList);

Switch 컴포넌트를 차일드 컴포넌트로 넣고 prop으로 list들을 전달한다.

 <CustomizedSwitches
                inProgressList={inProgressList}
                recentList={recentList}
              />

1)-(2)
Switch 컴포넌트에서 useState로 사용자가 inProgress를 눌렀는지 아닌지 구분할 수 있도록 해준 후에 state가 true 즉 inProgress 버튼을 눌렀다면 inProgressList를 map으로 보여주고 아니라면 모두인 List를 map하는 것을 보여준다.
또한 앞써 만들어준 CardComponent를 사용하고 prop으로 데이터를 넘겨주어 컴포넌트 또한 사용하였다.

export default function CustomizedSwitches({ inProgressList, recentList }) {
  const [checked, setChecked] = useState(false);

  const handleChange = () => {
    setChecked((prev) => !prev);
  };

  console.log(checked);

  return (
    <Layer>
      <FormGroup>
        <Stack direction="row" spacing={1} alignItems="center">
          <Typography>Show All</Typography>
          <AntSwitch
            checked={checked}
            onChange={handleChange}
            inputProps={{ "aria-label": "ant design" }}
          />
          <Typography>In progress</Typography>
        </Stack>
      </FormGroup>
      <div>
        {checked === true ? (
          inProgressList.map((todo) => <CardComponent todo={todo} />)
        ) : (
          <CardList>
            {recentList?.map((todo) => {
              return <CardComponent todo={todo} />;
            })}
          </CardList>
        )}
      </div>
    </Layer>
  );
}
profile
연습일지

0개의 댓글