과제
- 커스텀 훅 만들기
- 무비 앱에 실시간 채팅기능 구현
과제 결과
커스텀 훅 만들기
- 팀 별로 fetch hook, search hook, pagination hook, 즐겨찾기 hook을 만들어야했는데 나는 pagination hook을 만들기로 하였다.
// usePagination.jsx
export function usePagination({page, setActivePage}) {
const [startPage, setStartPage] = useState(1);
const lastPage =
page.count !== null ? Math.ceil(Number(page.count) / page.limit) : 0;
// 각 번호를 클릭했을 때 id 값을 가져와서 activePage state에 page 값을 저장
const onClickPage = event => {
const activePage = Number(event.target.id);
setActivePage(activePage);
};
const onClickPrevPage = () => {
if (startPage === 1) return;
setStartPage(startPage - 5);
setActivePage(startPage - 5);
};
const onClickNextPage = () => {
if (startPage + 5 <= lastPage) {
setStartPage(startPage + 5);
setActivePage(startPage + 5);
}
};
return {
startPage,
lastPage,
onClickPage,
onClickPrevPage,
onClickNextPage,
};
}
// 페이지네이션 컴포넌트 부모 컴포넌트에 state 값 저장, 해당 데이터 패치
const [activePage, setActivePage] = useState(1);
const activeUrl = `오픈API_링크&page=${activePage}`;
return (
<>
...
<Pagination
page={{count: payload.movie_count, limit: payload.limit}}
setActivePage={setActivePage}
activePage={activePage}
/>
...
</>
);
- 오픈 api 데이터 값 중에서 page를 fetch하여 page.count와 page.limit를 불러왔다.
- 총 데이터 count 값에서 한 페이지에 불러올 수 있는 limit 값을 나눈다. 그리고 나눈 값이 소수점 자리이면 안되기 때문에 Math.ceil로 소수점을 잘라주었다.
- prev와 next 버튼은 만들었지만 해당 데이터가 그렇게 많지 않아서 다음와 이전 버튼은 따로 사용하지 못했다.
실시간 채팅 기능 구현
- 지난 실습 시간에 배웠던 socket.io와 socket.io-client package를 활용하여 node 서버를 생성했다.
- username을 실시간 채팅 내에 넣는 것이 어색하여 따로 컴포넌트를 생성하여 헤더에 설치했다.
- 또한 username을 localStorage에 저장하여 만약에 한 번 username을 입력했다면 다시 입력하지 않아도 되게 설정했다.
- 그리고 username을 입력하지 않으면 경고 메세지가 뜬다.
// useLiveChat.jsx
...
const handleUsername = e => {
setUsername(e.target.value);
};
const onEnterUsername = e => {
if (e.key === "Enter") {
localStorage.setItem("username", username);
window.location.reload();
}
};
// LiveChat.jsx
...
const [isActive, setIsActive] = useState(false);
const {setMessage, message, chats, handleSubmit} = useLiveChat();
const handleToggle = () => {
setIsActive(prev => !prev);
};
return (
<>
{!isActive ? (
<div onClick={handleToggle} className="live_chat_open">
...
</div>
) : (
<section className={`live-chat-modal ${isActive ? "on" : ""}`}>
...
</section>
</section>
)}
</>
);
- isActive라는 boolean 상태 값을 사용하여 클릭 시에 켜지고, x 표시에도 handleToggle을 클릭 이벤트로 입력하여 클릭 시에 꺼지도록 설정했다.
// Username.jsx
const {savedName, username, onEnterUsername, handleUsername} = useLiveChat();
return (
<>
{!savedName ? (
<input
className="username-input"
onChange={handleUsername}
onKeyPress={onEnterUsername}
name="username"
value={username}
placeholder="사용자 이름을 입력해주세요."
/>
) : (
<p className="username">{savedName}</p>
)}
</>
);
- savedName은 로컬스토리지에 저장된 값이다. 저장된 값이 있으면 p 태그의 사용자 이름이 나타나고, 없으면 input 태그가 나타나도록 조건문을 설정했다.
- 처음에는 useState에 저장된 username을 사용하려고 했지만, username이 input의 e.target.value에 연결되어 있어서, input에 값이 하나라도 들어가는 즉시 화면이 변경되어서 로컬스토리지에 저장된 값을 가져왔다.
본 후기는 유데미-스나이퍼팩토리 10주 완성 프로젝트캠프 학습 일지 후기로 작성 되었습니다.
'외부활동 > 유데미X스나이퍼팩토리' 카테고리의 다른 글
[유데미x스나이퍼팩토리] 10주 완성 프로젝트 캠프 29일차 - 무비앱을 리덕스를 사용하여 데이터 흐름 관리해보기 (0) | 2023.07.04 |
---|---|
[유데미x스나이퍼팩토리] 10주 완성 프로젝트 캠프 28일차 - Redux 소개 및 기본 개념 (0) | 2023.07.03 |
[유데미x스나이퍼팩토리] 10주 완성 프로젝트 캠프 26일차 - KPT, 회고 (0) | 2023.07.01 |
[유데미x스나이퍼팩토리] 10주 완성 프로젝트 캠프 25일차 - Component lifecycle에 대한 이해, Express, custom Hook 실습 (0) | 2023.07.01 |
[유데미x스나이퍼팩토리] 10주 완성 프로젝트 캠프 24일차 - Git Config, useReducer (0) | 2023.07.01 |