[TIL] 팬레터함 만들기 (3)

·2023년 11월 16일
1

TIL

목록 보기
36/85
post-thumbnail

[오늘 한 일]

  • 알고리즘 3문제 풀기
  • redux 브랜치 완성
  • context 브랜치에서 localStorage 사용하도록 수정
  • 수정기능 mutable -> imutable 하게 변경
  • formatDate 함수 변경
  • background-img 고정되도록 수정

어제 context 브랜치가 생각보다 빨리 끝나서 바로 redux 브랜치를 작업했다.

context보다는 수정해야 할 사항이 많았다. (계속 발견되는 수정사항..)
우선 index.js를 다음과 같이 수정하고, 리덕스를 설정하기 위한 세팅을 했다.

// index.js
...
import { Provider } from "react-redux";
import store from "./redux/config/configStore";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <Provider store={store}>
    <App />
  </Provider>
);

configStore.js 파일을 만들고, 기존에 useContext를 사용해서 data라는 state를 가져오던 부분을 전부 useSelector를 사용해서 전역 state를 가져오도록 수정했다.
reducer를 작성하는 부분에서 CREATE, DELETE 부분은 dispatch로 action객체를 보내서 수행했는데, UPDATE하는 부분을 어떻게 dispatch로 보내야 할지 감이 오질 않았다. 그 과정에서 기존 updateComment함수가 mutable하다는 것도 깨닫게 되었다.😂 결국 세 브랜치 모두 update 하는 부분을 수정하게 되었다.

updateComment (imutable)

// 수정 전
const updateComment = () => {
    if (textarea === comment.content) alert("수정사항이 없습니다.");
    else {
      const result = window.confirm("이대로 수정하시겠습니까?");
      if (result) {
        data.find((item) => item.id === id).content = textarea; // mutable 👎
        navigate("/");
      } else return;
    }
  };

원래 이렇게 updateComment 함수를 사용하고 있었는데, 해당하는 요소를 find로 찾아서 그 content에 textarea 값으로 바로 바꿔주고 있었다. (뭔가 동작은 하는데 계속 찜찜함이 남아있던 이유가...)

const updateComment = () => {
    if (textarea === comment.content) alert("수정사항이 없습니다.");
    else {
      const result = window.confirm("이대로 수정하시겠습니까?");
      if (result) {
        setData(
          data.map((item) => {
            if (item.id === id) return { ...item, content: textarea };
            else return item;
          }) // imutable 👍
        );
        navigate("/");
      }
    }
  };

그리고 나서 위와 같이 map 메서드를 활용해서 기존 state에 직접 접근하지 않고 setData 함수를 통해 imutable 하게 수정했다.
그리고 리덕스 브랜치의 reducer도 다음과 같이 수정했다.

// reducer
const comment = (state = initialState, action) => {
  switch (action.type) {
    case CREATE:
      return [action.payload, ...state];
    case DELETE:
      return state.filter((item) => item.id !== action.payload);
    case UPDATE:
      return state.map((item) => {
        if (item.id === action.payload.id)
          return { ...item, content: action.payload.textarea };
        else return item;
      });
    default:
      return state;
  }
};

formatDate

원래 기존에는 코멘트에 시간을 표시하기 위해 함수를 DIY로 만들어서 쓰고 있었다.ㅋ

const formatDate = () => {
    const date = new Date();
    const year = date.getFullYear();
    const month = date.getMonth() + 1;
    const day = date.getDate();
    const hours = date.getHours();
    const minutes = date.getMinutes();
    const seconds = date.getSeconds();
    return `${year}.${month}.${day}  ${hours}:${minutes}:${seconds}`;
  };

Date.now() 로 현재 시간을 밀리초로 받아와서.. 년,월,일,시,분,초를 구하고 2022.11.16 11:10:11 과 같은 형식으로 포맷팅을 하고 있었는데...

const formattedDate = new Intl.DateTimeFormat("ko-KR", {
    dateStyle: "full",
    timeStyle: "short",
  }).format(new Date());

DateTimeFormat이라는 내장함수가 있다는 걸 알게되었다..😂 바로 수정..

background-img 고정

body {
    font-family: "Helvetica", "Arial", sans-serif;
    line-height: 1.5;
    box-sizing: border-box;
    background-image: url("/toy-story.jpg");
    background-size: cover;
  }

원래 background-size: cover로 꽉 차게 배경 이미지를 배치했는데,
comment가 입력될 때마다 전체 창의 height 가 커지면서 배경 이미지도 같이 커지는 문제가 있었다... 이것도 도움을 받아서 수정하게 되었다.

body {
    font-family: "Helvetica", "Arial", sans-serif;
    line-height: 1.5;
    box-sizing: border-box;
    background-image: url("/toy-story.jpg");
    background-size: cover;
    background-attachment: fixed; /* 추가 */
    background-repeat: no-repeat; /* 추가 */
  }

끝난 줄 알았는데 계속 수정해야 할 것들이 나온다.😂
소프트웨어도 살아있는 생명체 같아서 계속 들여다보고 관심 가져주고 해야
에러도 안생기나보다...
내 프로젝트를 여러 사람에게 공유하고, 다른 사람의 프로젝트도 보다 보니
수정해야 할 점들이 계속 생긴다. 이래서 피드백, 코드리뷰가 중요한가보다.

profile
느리더라도 조금씩, 꾸준히

0개의 댓글