Memoirs/부트캠프 기록

인스타그램 클론 코딩

conqueror-G 2022. 6. 16. 21:35

:: 구현 목표 

  1. Login - 사용자 입력 데이터 저장
  2. Login - 로그인 버튼 활성화
  3. Login - 프론트 앤드 ~ 백 앤드 간 통신
  4. Main - 댓글 추가 기능
  5. Main - 댓글 컴포넌트화 + props로 데이터 전달
  6. Main - 댓글 삭제 기능

:: 구현 사항 설명 

  1. Login - 사용자 입력 데이터 저장
  • 하나의 state로 다수의 input을 효율적으로 제어하기 위해 객체 데이터 타입으로 지정했습니다.

변경전

const [userId, setUserId] = useState();
const [userPw, setUserPw] = useState();

변경 후

const [userInfo, setUserInfo] = useState({
  userId: "",
  userPw: ""
});
  • input에서 입력되는 값을 userid와 userPw에 전달하기 위해 세 개의 함수를 사용하고, onChange외에도 onKeyUp을 사용해서 해당 기능을 구현했었는데 하나의 이벤트로만 구현가능하고, 비구조 할당을 이용해서 이후에 인풋 태그가 추가되더라도 간편하게 사용할 수 있도록 했습니다.

변경 전

const idLength = (event) => {
  setUserId(event.target.value.length);
};
const pwLength = (event) => {
  setUserPw(event.target.value.length);
};
const compare = (value) => {
  userId > 0 && userPw > 0 ? setEnabled(!value) : setEnabled(value);
};

변경 후

const inputHandler = (event) => {
  const { name, value } = event.target;
  setUserInfo((prev) => {
    return { ...prev, [name]: value };
  });
};
  1. Login - 로그인 버튼 활성화
  • 버튼의 활성화/비활성화를 state로 관리했었는데, 불린 값을 받는 변수로 수정 했습니다.

변경전

const [enabled, setEnabled] = useState(enabled);

변경 후

let enabled = !Boolean(
  userInfo.userId &&
    userInfo.userPw.length >= 5 &&
    userInfo.userId.includes("@")
);
  1. Login - 프론트 앤드 ~ 백 앤드 간 통신
  • 어떻게 통신하는지는 알겠는데.. 자세히 몰라서 강의자료 읽고 블로깅 할 예정입니다. 블로깅 끝나면 링크 달아놓겠습니다.
  1. main - 댓글 추가 기능 구현 + 댓글 컴포넌트화 + props로 데이터 전달
  • spread operator를 사용해서 배열에 사용자가 입력한 글이 담기는 것이 제일 기억에 남습니다. 로그인 기능을 구현할때에도 객체의 값을 덮어쓰기 위해서 사용했었지만 메인페이지에서 댓글을 구현할 때도 빈 배열에 사용자가 입력한 글이 담길 때 과정이 매우 단순했습니다.
    객체
{...obj, [event.target.name] : event.target.value } 

배열

[...arr, comment]
  1. main - 댓글 삭제 기능
    filter 함수를 사용해서 유저가 삭제하려는 아이디를 제외한 나머지를 반환합니다.
const removeComment = () =>
    setCommentData(prev => prev.filter(el => el.userId !== commentDataId));

:: 성장 포인트 

  1. state를 사용하는 규칙에 대해 알게되었습니다. 버튼을 활성화하는 과정에서 3번을 범했습니다. 버튼을 활성화하는 disabled 속성의 값을 state로 작성했었는데, 그 state에 연결된 다른 state가 2개이상이었습니다.
  1. 부모로부터 props를 통해 전달됩니까? 그러면 확실히 state가 아닙니다.
  2. 시간이 지나도 변하지 않나요? 그러면 확실히 state가 아닙니다.
  3. 컴포넌트 안의 다른 state나 props를 가지고 계산 가능한가요? 그렇다면 state가 아닙니다.
  1. 비동기적 특성에 대해 알게되었습니다. 1번과 연관되는 내용인데, 이 부분은 세션을 통해서 들었던 내용이지만, 제가 직접 겪어보기 전까지는 와닫지 않는 내용이었지만 덕분에 변수와 state에 대해 더 확실하게 깨달았습니다.
  2. 하나의 state에 객체를 사용해서 데이터를 관리할 때 예제 코드가 너무 이해가 안갔었는데, 지현님과 해당 코드에 대해 대화를 나누며 해결한게 너무 기억에 남습니다.
  3. prettier/prettier error가 계속 발생했습니다, 이것에 대해 여러가지 시도했습니다.
    해본 방법
  • yarn install (해결 안됬습니다.)
  • yarn upgrade -R eslint (해결 안됬습니다.)
  • 들여쓰기를 탭으로 변환 해봤습니다. (해결 안됬습니다.)
  • .esLint.js에서 해당 내용이 있는지 확인 했습니다 (있습니다.)
"prettier/prettier": [
      "error",
      {
        "endOfLine": "auto"
      }
    ]
  • 줄 시퀀스의 끝 선택이 LF인지 확인 했습니다. (맞습니다.)
  • prettier, eslint의 extention과 충돌할까 해서 둘다 사용안함으로 설정하고 확인했습니다. (해결 안됬습니다.)
  • prettier와 eslint extention을 재설치하고 재부팅하니까 그제서야 해결됬습니다.
  1. map함수의 사용법이 아직은 어렵습니다.. 특히 key값에 관련된 내용이 이해가 안가는데, 사용만 해봤네요. 더 공부해봐야겠습니다.
  2. 스택오버플로우에 더 좋은 방법으로 비구조 할당을 제시해주신 분이 있었습니다. 당시에는 무슨 내용인지 이해를 못했는데.. 팀원분들과 같이 공부하다가 더 잘 알게되어 코드에 적용해 볼 수 있었습니다.
  3. 댓글 삭제 기능을 구현하다가 2가지 주의사항을 경험했습니다.
  • 컴포넌트에 key값을 주는 과정에서 해당 컴포넌트에 key를 줬으나 중복으로 li태그에 다시한번 주며 해결하지 못했던 경험이 있습니다.
{commentData.map(name => (<CommentList key={name.userId}/>}
<li  key={key} className="postingCommentList">
  • 컴포넌트에 key를 props로 전달해서 id값을 주려했는데, 사실 안되는 행위였습니다. key는 props로 전달할 수 있는 것이 아니라 input의 name같은... 객체의 속성이기 때문에 props로 전달이 안되고, id를 아예 전달해야합니다.
<CommentList commentDataId={name.userId} key={name.userId} />;