yehey's 공부 노트 \n ο(=•ω<=)ρ⌒☆

[CEOS - 2주차 미션] react-messenger 만들기 본문

개발/프로젝트

[CEOS - 2주차 미션] react-messenger 만들기

yehey 2021. 4. 11. 14:40

이번 세오스 미션은 난이도가 있었다. 그렇다고 이전 미션이 쉬웠다는 뜻은 절대 절대 아님

이전 미션은 코드를 작성하는게 어려웠다면 이번 미션은 react를 사용하는 법과 같은 개념을 이해하는게 힘들었다.

react 독학하면서 메신저 만들기... 덕분에 시간 끌지 않고 온전히 react에 집중할 수 있는 시간이었다.

이번 코드는 길기도 하고 파일이 여러개라서 깃헙주소만 남겨놨다.

미션이 기본으로 class형이 아닌 함수형 component를 사용하라고 되어있어서 Hook 도 함께 사용했다. 

Hook 이해하는게 제일 어려웠고 아직 여전히 이해하지 못한 것 같긴하다. 앞으로 하면서 이해해봐야지

 

react 공부하고 직접 짜보면서 헷갈렸던 부분이나 남기고 싶은 부분만 부분적으로 정리해보았음!

//MessageInputBar.js

export default function MessageInputBar({ clickInputButton }) {
  const [messageUserInput, setMessageUserInput] = useState('');

  function enterPressed(e){
    if(e.key === 'Enter'){
      handleClickInputButton();
    }
  }

  function handleChange(e) {
    setMessageUserInput(e.target.value);
  }

  function handleClickInputButton() {
    if(messageUserInput !== '') {
      clickInputButton(messageUserInput);
      setMessageUserInput('');
    }
  }
  return (
    <MessageInputContainer>
      <MessageInputBox 
        placeholder="message" 
        value={messageUserInput}
        onChange={handleChange}
        onKeyPress={enterPressed}
      />
      <MessageInputButton onClick={handleClickInputButton}>send</MessageInputButton>
    </MessageInputContainer>
  );
}

 

  • MessageInputBar({ clickInputButton }): {clickInputButton}은 부모? 상위 컴포넌트로부터 호출할 때 전달받은 함수, 이 함수를 통해 하위 컴포넌트의 훅 변수 값을 상위 컴포넌트로 전달할 수 있다. 
  • MessageInputBox: 메시지 입력을 받는 창, placeholder: 메시지가 입력되지 않았을 때 보이게 할 것
    value: messageUserInput을 값으로 넣어줌, onChange: 값이 변했을 때 handleChange 함수가 실행
    onKeyPress: 키보드가 입력되면 enterPressed 함수가 실행
  • MessageInputButton: 메시지 입력하고 누르는 버튼, onclick: 클릭되었을 때 handleClickInputButton 이 실행된다
  • const [messageUserInput, setMessageUserInput] = useState('');
    : Hook, 상태관리용(?), messageUserInput이 변수 역할, setMessageUserInput 함수를 통해서 변수 값을 변화시킬 수 있음,
    useState를 이용해서 messageUserInput 변수를 초기화한다. 값을 넣어서 초기화할 수도 있음
  • enterPressed(e): e는 이벤트, 만약 눌린 키가 enter라면 버튼을 클릭할 때 실행한 함수와 같은 함수(handleClickInputButton)를 실행한다.
  • handleChange(e): MessageInputBox에서 바뀐 값을 setMessageUserInput 함수를 통해 messageUserInput에 대입, 메시지 박스 값이 바뀔 때마다 실행되며 훅 변수 값을 상시로 바꿔주는 함수
  • handleClickInputButton():messageUserInput 값이 없지 않으면 (값이 있으면)  상위 컴포넌트로부터 받은 clickInputButton을 실행한다. 그리고 훅 변수의 값을 다시 초기화해준다.
function App() {
  let chattingUser = 1;
  const [userChattingMessageSet, setUserChattingMessageSet] = useState([]);

  function clickProfileImageButton(userID){
    chattingUser=userID;
  }
  function clickInputButton(messageUserInput) {
    let ID = Date.now();
    setUserChattingMessageSet(formerMessage => [...formerMessage, {chattingUser: chattingUser, messageContext: messageUserInput, id: ID}]);
  }

  return (
    <Container >
      <TopBar clickProfileImageButton={clickProfileImageButton}/>
      <MessageBox userChattingMessageSet={userChattingMessageSet}/>
      <MessageInputBar clickInputButton={clickInputButton}/>
    </Container>
  );
}

 

  • userChattingMessageSet : 사용자 채팅 메시지와 아이디를 딕셔너리로 저장하는 셋, 배열, 빈 배열로 초기화
  • clickProfileImageButton(userID): 하위 컴포넌트에서 전달받은 userID를 chattingUser에 대입, 하위 컴포넌트에서 사용자 프로필 이미지가 클릭되면 실행되는 함수
  • clickInputButton(messageUserInput) : 하위 컴포넌트에서 userInputButton이 눌리면 실행되는 함수, 메시지 딕셔너리 id는 생성 날짜, setUserChattingMessageSet에 원래 셋은 그대로 저장하고(변화가 없기 때문에) 새롭게 메시지 딕셔너리를 추가해서 저장한다.
    우리가 보기에는 값을 전부 변경하는 것처럼 짜여있지만 react 내부에서 자체적으로 변화한 부분만 탐색해서 바꾼다고 한다.
  • 이렇게 생성된 userChattingMessageSet을 MessageBox에 전달해준다. (그래야 채팅 메시지가 창에 뜸!)

useState 를 이용한 Hook 외에도 useEffect도 사용했지만 아직 이해가 잘 가지 않아서 정리를 할 정도는 아니라고 생각해서 따로 정리하지 않았다. 아마도 다음 과제에서는 정리하지 않을까 싶음!

(다음과제는 채팅창 말고 그냥 채팅 그자체 만들어오기...^^ 미쳐버린 진도.. 아직 리액트도 잘 모르는데 라우팅까지 하핳 행복하다 ^^)

 

더보기

느낀점

js처럼 react도 처음이라 잘 했는지는 모르겠습니다. 그래도 할 수 있는만큼 열심히 했더니 기능은 전부 구현한 것 같아서 상당히 뿌듯했지만 여전히 react를 완전히 이해하지는 못한 것 같아서 아쉬움은 많이 남는 것 같아요. 앞으로 react를 계속 다루는 만큼 이해도도 높아지기를 기대하고 있습니다. Hook은 useState와 useEffect 만 사용했는데 useEffect는 이해가 조금 부족한 것 같아요. 다음 과제를 하면서는 react랑 더 친해졌으면 하고 있습니당..

 

저는 기능은 추가를 못할 것 같아서 꽃말이 [중간고사]인 벚꽃에서 영감을 받아 핑크핑크 코랄코랄하게 꾸며보았습니다..ㅎ 전 사실 핑크를 좋아하진 않아요. 디자인파트 만났을 때 coral 추천해주시고 색조합도 추천받아서 반영했습니다! 디자인 구려하기 없기...>.0

 

사진이랑 프로필은 우기를 너무너무 좋아하는 수호를 위해 바꿨다. 수호야 행복하지..? 줄 수 있는게 이거밖에 없다 ㅎㅎ

 

https://react-messenger-13th-git-main-yehey-1030.vercel.app/

 

key Question

1. virtual DOM이 무엇일까요? 

React는 실제로 DOM을 제어하는 방식이 아니라 중간에 가상의 DOM을 이용해서 DOM을 직접 제어하지 않음

실제 DOM의 구조와 비슷한 React 객체의 트리로 개발자가 virtual DOM을 제어하고, react가 적절하게 virtual DOM을 DOM에 반영한다.

react가 자체적으로 실제 DOM과 비교해서 변경된 사항이 있는지 확인하기 위해 존재하는 DOM아닐까..? 라는 생각을 합니당

Virtual DOM은 변화가 발생하면, 실제 DOM에 적용되기 전에 Virtual DOM에 우선 적용을 시켜봅니다. 실제 DOM에 바로 적용하나, Virtual DOM에 적용하나 같은 연산 비용이 필요할 거라 생각하실 수 있지만, Vitual DOM은 랜더링 과정이 필요 없기 때문에 연산 비용이 실제 DOM보다 적습니다.

Virtual DOM에서 이러한 연산이 끝나고 나면, 최종적인 변화를 실제 DOM에 전달해줍니다. 즉, 10번의 작업을 하나로 묶어 딱 한 번 전달해 줍니다. 물론, 레이아웃 계산과 리랜더링하는 과정의 규모는 커지겠지만, 횟수를 줄이는 것으로 충분히 연산 비용을 적게 만들어 줍니다.

 

2. 미션을 진행하면서 느낀 react의 장점?

JSX 방식으로 컴포넌트를 생성하는 것이 가장 큰 장점같았습니다. 한 기능을 할 수 있는 태그를 묶어서 하나의 컴포넌트를 만드니 직접 사용할 때도, 다른 사람의 코드를 읽을 때도 더 잘 와 닿았던 것 같습니다.

또 리액트의 컴포넌트는 html 태그를 사용하는 것처럼 사용할 수 있으니 그것만으로도 큰 장점처럼 느껴졌습니다.

사용하면서 느낀 장점은 아니지만 리액트의 가장 큰 장점은 virtual DOM이라고 생각을 합니다. 앞서 virtual DOM에 대해서 이야기를 할 때도 보셨겠지만 여러번의 랜더링 작업을 묶어 하나로 전달하니 연산이 적어지고 알아서 바뀐 DOM을 파악해주니 이게 react의 가장 큰 장점이라는 생각이 듭니다.

하지만 여전히 react는...어렵고 어렵고 또 진짜 어려운 것 같습니다.. 앞으로 더 배우면서 다른 장점들도 알아갈 수 있으면 좋을 것 같습니다. 😉

3. react에서는 어떻게 상태를 관리할까요?

class 형의 경우에는 state를 이용하는 듯 하고

함수형의 경우에는 Hook을 이용해서 관리한다

useState를 이용해서 state라는 값을 초기화할 수 있고

이후에 setState라는 함수를 이용해서 state 값을 재설정할 수 있음

 

+ 다른 사람의 의견 중에 인상깊었던 것은 props도 상태관리의 일종이라고 생각한다는 것, 생각도 못했던건데 맞는 것 같음!

 

 

https://github.com/yehey-1030/react-messenger-13th

 

yehey-1030/react-messenger-13th

13기 프론트엔드 2,3주차 미션 react-messenger를 진행하기 위한 레포지토리입니다 - yehey-1030/react-messenger-13th

github.com

 

Comments