이름바꾸기 기능 정리하기

Imnottired·2023년 6월 4일
0
post-thumbnail

기능

프로젝트에서 구현한 기능 중 이름 바꾸기 기능이 있다.

이름(돼지)을 누르면,

input창이 나타나고 작성을 하고나서 엔터를 누르면 변경이 된다.

만약에 취소를 하고 싶으면, input 창 밖을 누르면 blur이벤트가 일어나서
저장해두었던 바뀌기 전 이름으로 돌아간다.


글 작성 동기

간단해보이는 기능이었는데, 생각보다 어려웠다.
큰 그림을 한번에 생각해내기 어려웠고, 쉽게 생각했어서
생각나는대로 작성하였다.
그래서 플로우가 많이 꼬였고, 문제가 많았다.

블로깅을 통해서 플로우를 다시 한번 정리할 것이다.
이를 통해 큰그림을 명확하게 그려보며 다음에는 헷갈리지 않을 것이다.




코드

const [text, setText] = useState<string>(rank.name);
const inputRef = useRef<HTMLInputElement>(null);
const [savedText, setSavedText] = useState<string>("");
const [isEditing, setIsEditing] = useState<boolean>(true);

  const handleClick = () => {
    setIsEditing(!isEditing);
    setSavedText(text);
  };
  
   {isEditing ? (
          <div
            className="w-32 truncate text-sm font-bold cursor-pointer hover:underline"
            onClick={handleClick}
          >
            {text}
          </div>
        ) 

먼저 코드를 보면, props로 rank라는 데이터를 받으면, name value를 text에 할당해준다.
그리고 text로 UI에 출력을 하고, isEditing을 통해서 수정 여부를 컨트롤한다.
이름을 클릭하게되면, isEditing의 상태를 바꾸어주고, 기존의 text를 savedText로 백업해준다.(이는 text가 수정을 하고 취소 했을 때를 대비해 백업을 해두는 것이다.)


  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setText(e.target.value);
  };
  const handleCancel = () => {
    setIsEditing(!isEditing);
    setText(savedText);
  };
  
(
          <input
            type="text"
            ref={inputRef}
            value={text}
            onChange={handleChange}
            onBlur={handleCancel}
            spellCheck={false}
            onKeyDown={(e) => {
              if (e.key === "Enter") {
                handleSave();
              }
            }}
            className="w-32 border border-gray p-2"
          />
        )}

먼저 input에는 text 값이 들어오고 input 값을 수정하면 onChange로 업데이트가 된다.

코드에는 없지만 inputRef.current.focus()를 사용하여서 포커스가 가게 만들었다.
여기서 유저가 focus가 벗어나게된다면 blur 이벤트가 발생한다.

handleCancel 함수 이벤트가 일어난다.
이때 isEditing이 업데이트가 되어 다시 div로 바뀐다.
savedText(백업해두었던 값)를 text에 넣어서 기존의 값으로 바꿔준다
(onChange를 통해 업데이트 되었던 값들을 초기화한다).

  const handleSave = () => {
    setIsEditing(!isEditing);
    const data: Save_data = { ...rank, name: text };
    patch_candidates(accessToken || "없음", data)
      .then((res) => {
        console.log(res, "res");
      })
      .catch((err) => {
        console.log(err, "err");
      });
  };

마지막으로 handleSave를 통해 저장을 한다.
setIsEditing을 통해 input에서 div로 돌려주고,
patch_candidates 첫번째 인자에는 accessToken을 넣고,
두번쨰 인자에는, data를 넣어주며 마무리가 된다.


헷갈렸던 포인트

처음에는 코드를 줄이고자
4개의 함수를 사용하는 것이 아닌, 2개의 함수로 처리하고자 하였다.
(재사용성을 높이고, 코드를 줄이고자하였다)
그래서 그 조건에 맞추어서 처리하다보니 플로우가 꼬였고,
결국 간단하게 접근할 수 밖에 없었다.

역할을 확실하게 나누어서 분배하고 정리하니
실수도 찾기 좋았고, 큰 그림을 그리기도 쉬웠다.

부트캠프에서 메인프로젝트를 하면서 컴포넌트화를 도전하였다.
처음하는 것도 컴포넌트화를 시도하였는데, 굉장히 시간이 오래걸렸다.
(생각이 정리가 잘되지않았다)

요즘 드는 생각은 컴포넌트화를 바로 한다면 좋겠지만,
하드 코딩을 하면서 큰그림을 이해하고, 컴포넌트화를 하는 것이 순리같다.

끗!

profile
새로운 것을 배우는 것보다 정리하는 것이 중요하다.

6개의 댓글

comment-user-thumbnail
2023년 6월 7일

컴포넌트화의 중요성 요즘 저도 많이 느끼고 있는 것 같아요..! 고생하셨습니다 ㅎㅎ

답글 달기
comment-user-thumbnail
2023년 6월 8일

간단해 보여도 인풋으로 변경, 데이터 저장, 수정 기능들이 압축해서 들어있네요 ! 고생하셨습니당

답글 달기
comment-user-thumbnail
2023년 6월 11일

일단 돌아가게 만들고 나중에 컴포넌트화하면 되지요ㅎㅎ 잘 읽었습니다 👍

답글 달기
comment-user-thumbnail
2023년 6월 11일

악 저도 컴포넌트화 하려고 함수 나누는데 머리 깨질거같아요 어렵슴돠 ㅋㅋ ㅠㅠ

답글 달기
comment-user-thumbnail
2023년 6월 11일

좋네요! 확실히 귀찮으면 귀찮을수록 나중이 더 편한 거 같습니다. 근데 너무 분리하면 또 안좋고,, 딜레마에 빠지곤 합니다 ㅋㅋㅋ

답글 달기
comment-user-thumbnail
2023년 6월 11일

각 역할을 구분해서 작업 하셨군요! 좋은 방법인것 같아요!

답글 달기