목차
반응형
전체 유저에서 접속중인 유저만 불들어오도록 변경
서버에서 전체 유저 리스트를 받아와 현재 온라인인 유저만 불이 들어오도록 했다.
일단 useQuery를 사용한 서버의 전체 유저 데이터를 받아왔다.
const { allUsers } = useAllUsers();
그리고 실시간으로 접속중인 유저의 데이터는 socket.io를 사용해서 가져오고 allUsers, onlineList는 모두 이름 순으로 정렬시켰다.
useEffect(() => {
// 서버에서 온라인 리스트 배열로 받음
socket?.on('onlineList', (data) => {
// 배열에서 중복요소 제거해서 새로운 배열 생성
const userArray = data.filter((ele, i) => {
return data.indexOf(ele) === i;
});
// 새로운 배열 온라인리스트 state에 저장
setOnlineList(userArray);
});
return () => {
socket?.off('onlineList');
};
}, [socket, onlineList]);
if (allUsers && onlineList) {
allUsers.sort();
onlineList.sort();
}
전체 유저의 리스트를 map메소드로 반복시킬 때 온라인 유저는 클래스 isOnline true만들어 CSS로 처리했다.
<Container>
접속중인 유저
{allUsers.map((user, i) => {
const isOnline = onlineList.indexOf(user);
return (
<List className={isOnline < 0 ? 'offline' : 'online'} key={i}>
{user}
</List>
);
})}
</Container>
export const List = styled.div`
position: relative;
text-indent: 20px;
margin: 15px;
&:before {
content: '';
display: block;
position: absolute;
top: 50%;
left: 0;
transform: translate(0, -50%);
width: 10px;
height: 10px;
border-radius: 50%;
border: 1px solid var(--gray);
}
&.online:before {
background-color: var(--blue);
border: none;
}
`;
NavBar/홈페이지 UI스타일적용
NavBar는 필요한 메뉴, 로고, 프로필의 정보만 구성했고, 홈페이지에는 랜덤으로 바뀌는 포스터 구역과, 베스트/최신글, 온라인 유저로 구성해놨다.
글쓰기 모달창으로 변경
기존에는 홈페이지에서 바로 글을 작성 할 수 있도록 설정해놨는데 디자인 적으로 너무 뜬금 없이 배치되었다고 판단했다.
글쓰기 WRITE 메뉴나, 플로팅 버튼을 누르면 모달창이 나올수 있도록 구현했다.
모달창을 적용하면서 모달창 밖의 영역을 클릭 시 모달창이 닫힐 수 있도록 useOnClickOutsideModal 커스텀 Hook함수를 생성했다.
import React, { useEffect } from 'react';
function useOnClickOutsideModal(ref, handler) {
useEffect(() => {
// console.log(ref);
const listener = (e) => {
if (!ref.current || ref.current.contains(e.target)) {
return;
}
handler(e);
};
document.addEventListener('mousedown', listener);
document.addEventListener('touchstart', listener);
return () => {
// 컴포넌트가 언마운트 됐을 때 리턴 실행 (이벤트리스너들 삭제)
document.removeEventListener('mousedown', listener);
document.removeEventListener('touchstart', listener);
};
}, [ref, handler]);
return <div>useOnClickOutside</div>;
}
export default useOnClickOutsideModal;
모달창의 Form 태그를 useRef를 사용해서 DOM element를 선택할 수 있도록했다.
그리고 위의 Hook 함수는 클릭한 영역이 해당하는 ref와 동일하지 않을 경우 모달창을 닫는 status를 false로 만들어준다.
useOnClickOutsideModal(ref, () => {
setWirteModalOpen(false);
setIsBtnActive(false);
});
return (
<Container>
<Form onSubmit={onSubmit} ref={ref}>
<FormHeader>LIFE IS A SENTENCE</FormHeader>
<Input autoFocus autoComplete='off' type='text' name='post-writeModal' id='post-write-label' placeholder='들려주고 싶은 한 마디를 적어보세요. (최대 20자, 한글만 가능)' value={sentence} onChange={onChangeSentence} />
<Button buttonActive={buttonActive} id='Button' type='submit'>
작성 완료
</Button>
</Form>
</Container>
);
모달창의 바깥 영역을 클릭하면 닫히는 것을 확인 할 수 있다.
반응형