wecode 2차 프로젝트를 마치며

0

프로젝트 회고

목록 보기
5/5
post-thumbnail

이 글을 2차 프로젝트를 마치며 개인적으로 담당했던 부분에 대하여 자세하게 남기고자 씁니다.

프로젝트 구현 영상 : https://www.youtube.com/watch?v=3sZc05pvuCY


  • 가장 기본이자 쉽게 구현할 있다고 생각했던 Nav바이다.

  • 그런데 한가지 고민이 생겼다. "Nav바 상태나 회원정보는 쭉 유지하는게 어떨까?"라는 것이다.(위에서 해당 페이지를 알려주는 파란 밑줄도 Redux가 관리하는 값이다.)

  • 1차 프로젝트 때도 했던 고민인데 보통 사이트들은 로그인을 하면 그 로그인 정보를 가지고 페이지가 변해도 가지고 있는다.

  • 물론 페이지 이동 후 그때 그때 토큰값으로 계속 다시 회원정보를 받을 수 있을 것이다.

  • 그러나 component가 언마운트되고 마운트 되는 라이프사이클을 고민하면서 하다보면 뭔가 Nav나 컴포넌트들이 의도치않게 리로드될 수 있다.

  • 그렇다고 페이지마다 Nav로 모든 컴포넌트들을 다 감싸고 시작한다?

  • 여러 개발자가 협업하는 상황에서 시간에 쫒기며 개발하는 상황에서 조금이라도 서로 약속이 틀어지면 원하는 방향으로 될 것 같지않았다.

  • 그래서 난 이번에 배운 Redux가 해결책이라고 생각하였다.

  • navPick에 따른 색상변화를 위한 state,

  • 로그인 유무에 따른 한페이지에서도 다르게 보여주는 것을 위한 state,

  • 어느페이지에서건 로그인modal을 온오프 시켜줄 state,

  • 로그인종류(google, facebook, 일반)에 따른 다른 로그인, 아웃 로직이지만 유저에게는 하나의 버튼으로 보이게 하기 위한 state.

코드

//store/actions/index.js

// nav메뉴 클릭시 blue underline action
export const changeNavColor = pick => {
  return {
    type:"nav_pick",
    payload: pick
  }
}

// 로그인  action
export const changeLogin = check => {
  return {
    type:"login_check",
    payload:check
  }
}

// 로그인 종류에 따른 action
export const kindLogin = kind => {
  return {
    type:"login_kind",
    payload:kind
  }  
}

// modal창 들어갔나 나오게할 action
export const changeModal = onoff => {
  return {
    type:"modal_onoff",
    payload:onoff
  }
}

// profile창 updown하게 할 action
export const changeProfile = updown => {
  return {
    type:"profile_updown",
    payload:updown
  }
}

Login, 회원가입

  • 최초에 이메일을 입력받고 비회원이면 회원가입으로, 회원이면 password를 묻는단계로 이루어져 있다. 모든 단계가 modal로 이루어져 있으며 그렇기에 어떤 페이지에서든 nav를 통해 modal을 띄웠다가 off할 수 있다.

  • 즉, 글로벌하다는 뜻이다. 그렇기에 또한 store로 관리하도록 하였다.


코드

// modal 발생시 백그라운드에 추가되는 것
useEffect(() => {
  modalOnoff ? window.document.body.style.overflowY="hidden" : window.document.body.style.overflowY="scroll"  
}, [modalOnoff]);

const ModalBackground = styled.div`
  position:${props => props.modal?"fixed":""};
  display:${props => props.modal?"":"none"};
  opacity:${props => props.modal?"0.5":"0"};
  z-index:${props => props.modal?"10000":"-1"};
  top:0px;
  width:100%;
  height:100vh;
  background-color:black;  
`;

const ModalVisible = styled.div`
  position:${props => props.modal?"fixed":""};
  display:${props => props.modal?"":"none"};
  opacity:${props => props.modal?"1":"0"};
  z-index:${props => props.modal?"20000":"-1"};
  display:${props => props.isView===0?"":"none"};
  background-color:white;  
  top: 50%;
  left: 50%;
  width: 400px;
  height: calc(100vh - 150px);
  transform: translate(-50%, -50%);
  border-radius: 5px;
  overflow-y: scroll;   
`;
  • modal onoff시 사용되는 style. 여기서 중요한 점은 background에 검은 투명하게 백그라운드가 깔린다는 것. 용도는 모달이 띄워졌을 시 다른 컴포넌트들보다 위에 있고 그 위에 다시 모달이 올려져있는 레이어라는 것이다.
  • 또한 직접 dom접근을 하여 최상위의 body의 scroll을 막아주도록 하여 modal에 집중할 수 있도록 하였다.

이력서 페이지

  • 우선 이력서 페이지는 로그인 유무에 따라 보이는 정보가 다르다

  • 그렇기에 전역에서 관리되는 상태를 이용하여 이를 표현해주었다.
  • 이력서 페이지에서는 새롭게 글을 쓰는 것과 다시 불러와서 고치거나 그 글을 지울 수가 있다. 이런 기능자체는 그렇게 어렵지않게 할수가 있었다.
    그러나 문제는...
  • 이력서 리스트도 유저에 따라 데이터가 다르다. 고정값이 아닌 유저마다 다른 데이터를 받아와 하나의 이력서당 각각의 일관된 토글기능이 있는데 array의 map사용하여 list를 보여주면서 1개의 state 기능을 구현하는것이 생각보다 어려웠다.
  • 그래도 결국 실제 사이트 처럼 각각의 글을 토글을 키거나 끄거나 할 수 있으며 각각의 글을 삭제할 수도 있도록 구현하였다.

코드1

const CvPage = ( { loginCheck, history } ) => {
	
  //로그인 상태에 따라 보여줄 정보를 바꿀 state
  const [isLogin, setLogin] = useState(false)
  //각각의 토글기능 온오프를 위한 토클 state
  const [isToggle, setToggle] = useState(0)

  //로그인 상태에 따라 최초 정보를 위한 useEffect
  useEffect(() => {
    loginCheck?setLogin(true):setLogin(false)
  }, [loginCheck])
	
  //페이지 이동시 시작은 항상 scroll 재일 위니까!
  useEffect(() => {
    document.documentElement.scrollTop=0;
  }, [])
 
  
///// map mothod 부분
return (
    <>
      {data.resume && data.resume.map((item, inx) => {
        return (
          <Cover>
            <BoxWrap>    
              <InnerBox key={inx}>            
                <HeaderWarp onClick={() =>{moveDetailFunc(item.id); props.setToggle(0);}}>
                  <NameIng color={validation(item.intro)}>{item.title}</NameIng>
                  <DateSpan>{(item.updated_at).substring(0, 10)}</DateSpan>           
                </HeaderWarp>
                <TextIng color={validation(item.intro)}>         
                  <NonClickBox onClick={() => {moveDetailFunc(item.id); props.setToggle(0);}} color={validation(item.intro)}><span>{validation(item.intro)}</span></NonClickBox>
                  <ClickBox onClick={() => props.isToggle !== item.id ? props.setToggle(item.id) : props.setToggle(0)}><MdMoreVert/></ClickBox>                          
                </TextIng>       
              </InnerBox>
            </BoxWrap>
            <UserCvListToggle index={item.id} isToggle={props.isToggle} getFunc={getFunc}/>  
          </Cover>
        )
      })}
    </>
  )
}  


///토글부분 컴포넌트

 <ToggleBox isToggle={props.isToggle} index={props.index}>    
        <ul>
          <li onClick={() => props.getFunc}>이름 변경</li>
          <li>다운로드</li>
          <li onClick={deleteFunc}>삭제</li>
        </ul>    
      </ToggleBox>      
  
  • 이력서 리스트의 각각의 박스를 만들고 각각의 박스는 각각의 토글을 갖는다.
  • 각각의 토글버튼이 눌리면 그 버튼은 그 박스의 고유id값(map method에서 부여하는 index나 백엔드에서 부여한 고유 id를 이용하여 state에 담긴다.
  • state의 값과 고유의 id값이 일치하는 박스가 맞으면 토글은 온이 된다.

코드2

// 이력서페이지 최상위
   <Nav/>
      <Cv>
  	//비회원일시 보여주는 컴포넌트
        <NonUser isLogin={isLogin}>  
        </NonUser>
  	//회원일시 보여주는 컴포넌트
        <UserContents isLogin={isLogin}>
          //모든 토글을 끄게 할 리스트 뒤에 깔릴 백그라운드
          <Background onClick={() => setToggle(0)}/>
        </UserContents>       
      </Cv>
      <Footer/>
  • 그리고 토글박스 밖이 클릭될 경우 모든 토글이 꺼져야 되므로 최상위 부모에서 백그라운드를 만들어놓고 z-index를 이용하여 백그라운드>박스 순으로 하여 박스가 클릭되면 토글이 온, 배경이 클릭되면 다 꺼지도록 하였다.

느낀점...

리엑트는 재밌다. 아니 프론트 엔드는 재밌다. 너무나도 재밌었다.

생각대로 만들어지는 것을 볼때는 너무나 즐거웠다.

또한 새로운 기술(스타일 컴포넌트나 훅, 리덕스)을 사용하니 배울 때는 힘들었지만 그 뿌듯함은 더욱 높다.


이제는 지금 것 배운 것은 더욱 단단히, 더욱 내 것으로 만들 것이며

javascript는 더욱 깊게.!
더 나아가 typescript 등을 새롭게 공부할 것이다.

0개의 댓글