-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[4주차] 이희원 미션 제출합니다. #18
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
제가 사용해보지 않은 방식으로 (button과 같이 비슷한 컴포넌트를 한 파일에 작성하는 등 ) 구현하셔서 보면서 많이 공부할 수 있었던 코드였습니다! 그리고 주석으로 TODO를 작성해주시고 코드 설명을 상세하게 적어주셔서 리뷰하기 좋았던 것 같습니다! 👍🌟
4주차 과제도 정말 수고 많으셨습니다! 🍀
plugin: CracoAliasPlugin, | ||
options: { | ||
source: 'tsconfig', | ||
baseUrl: './src', | ||
tsConfigPath: './tsconfig.paths.json', | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 Craco를 사용하셨네요! 확실히 절대경로를 사용하니까 import문이 간결하고 깔끔해서 보기 좋은 것 같아요👍저도 다음번엔 CracoAlias 라이브러리를 사용해봐야겠습니다
width: 375px; | ||
height: 100vh; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
전체 화면크기를 width는 픽셀로 고정하고 height은 vh로 설정하신 이유가 따로 있으신가요?
// Clock : 상단 바 시간 | ||
|
||
export default function Clock() { | ||
const timeRef = useRef<any>(null); // 일단 any써뒀는데, 아닌 것 같음 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저도 궁금해서 찾아봤는데 HTMLParagraphElement
를 쓰는 방법이 있는 것 같아요! 아래 코드처럼 작성하면 어떻게 되는지 궁금하네요!
const timeRef = useRef<any>(null); // 일단 any써뒀는데, 아닌 것 같음 | |
const timeRef = useRef<HTMLParagraphElement | null>(null); |
export function MemberListItem(user: UserInterface) { | ||
return ( | ||
<ListItem user={user}> | ||
<div className="flex flex-col justify-center gap-1 grow"> | ||
<Link to={`${user.id}`}> | ||
{/* 사용자 이름 */} | ||
<div className="font-subtitle">{user.userName}</div> | ||
</Link> | ||
</div> | ||
<Link | ||
to={`/chat/${user.id}`} | ||
className="flex items-center justify-center mx-3" | ||
> | ||
<img | ||
src={CHAT} | ||
alt="chat" | ||
/> | ||
</Link> | ||
</ListItem> | ||
); | ||
} | ||
|
||
export function ChatListItem(user: UserInterface) { | ||
return ( | ||
<ListItem user={user}> | ||
<div className="flex flex-col justify-center gap-1 grow"> | ||
{/* 사용자 이름 */} | ||
<div className="font-subtitle">{user.userName}</div> | ||
{/* item 내용 미리보기 */} | ||
{user.lastMessage && ( | ||
<StyledMessagePreview className="text-body text-gray-500"> | ||
{user.lastMessage} | ||
</StyledMessagePreview> | ||
)} | ||
</div> | ||
<div className="text-caption text-gray-500"> | ||
{user.lastMessageTimeStamp} | ||
</div> | ||
</ListItem> | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
비슷한 기능을 하는 컴포넌트는 이렇게 한 파일로 작성하고 export 하는 방식은 한번도 생각해보지 못해서 너무 신기합니다 ㅎㅎ props drilling을 줄일 수 있는 좋은 방법이라는 생각이 드네요! 배워갑니다!
// 스타일을 동적으로 결정 | ||
const setMessageStyle = () => { | ||
let styleStr = ''; | ||
if (message.emoji) styleStr += 'mb-4 '; | ||
if (message.sender === 'me') { | ||
styleStr += | ||
currentUser.id === mainUser.id | ||
? 'bg-gray-50 text-gray-900 me-auto' | ||
: 'bg-primary text-white ms-auto'; | ||
} else { | ||
styleStr += | ||
currentUser.id === mainUser.id | ||
? 'bg-primary text-white ms-auto' | ||
: 'bg-gray-50 text-gray-900 me-auto'; | ||
} | ||
return styleStr; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
확실히 tailwind는 스타일을 동적으로 구현하는데 한계가 있어서 이런 부분에 있어서는 다른 라이브러리를 사용하는 게 좋은 것 같아요. 저는 그냥 style 태그를 사용했는데 styled components를 사용할 수도 있겠네요!
export const userSlice = createSlice({ | ||
name: 'user', | ||
initialState, | ||
reducers: { | ||
toggleUser: (state, action: PayloadAction<UserInterface>) => { | ||
state.currentUser = | ||
state.currentUser.id === state.mainUser.id | ||
? action.payload | ||
: state.mainUser; | ||
}, | ||
}, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
채팅방 내에서 프로필 클릭 시 유저 전환 이외에 유저 토글 함수를 사용하는 페이지가 따로 없는 것 같은데 유저 토글 기능을 전역 상태로 관리하는 이유가 있으신가요? (제가 놓친 기능이 있을 수도...)
const handleDoubleClick = (messageId: string) => { | ||
setSelectedMessageId(messageId); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이모지 선택을 위해 메시지를 더블클릭하면 텍스트와 요소들이 파란색으로 드래그 되는 현상이 있더라구요! 저도 이번주에 이모지 기능을 구현하면서 똑같이 겪었던 문제인데 event.preventDefault();
를 사용하여 해결했습니다. 혹시 도움되실까 해서 올려요~!!
const handleDoubleClick = (messageId: string) => { | |
setSelectedMessageId(messageId); | |
}; | |
const handleDoubleClick = (index: number, event: React.MouseEvent) => { | |
event.preventDefault(); // 요 라인 추가 | |
setSelectedMessageId(messageId); | |
}; |
희원님 이번주차 과제도 고생 많으셨습니당 ⸜(ˊᗜˋ)⸝ |
배포 링크
피그마 링크
기능
될것처럼 생겼는데 안되는 거
느낀점
useParam
을 갖고 넘긴 정보들을 가져올 수 있는데, 항상undefined
가 타입에 끼어들어와서 그거 처리해주는게 매우 번거롭고 귀찮았다.1. React Router의 동적 라우팅(Dynamic Routing)이란 무엇이며, 언제 사용하나요?
동적 라우팅: 사용자가 방문하는 페이지에 따라 다른 데이터를 기반으로 렌더링되는 라우트를 만드는 기능
이번 채팅 앱에서 사용자의 ID에 따라 다른 페이지로 이동하는 데, 여기서 동적 라우팅이 사용된다.
URL의 특정 부분을 변수처럼 처리하여 여러 페이지를 하나의 경로로 관리할 수 있다.
useParams
훅을 사용하여 URL에서 파라미터를 받아와서 컴포넌트 내에서 그 값을 활용할 수 있다.이때 해당 훅으로 받아오는 값들은 항상
undefined
도 타입으로 같이 반환하기 때문에 이 부분을 신경써서 구현해야 한다.2. 네트워크 속도가 느린 환경에서 사용자 경험을 개선하기 위해 사용할 수 있는 UI/UX 디자인 전략과 기술적 최적화 방법은 무엇인가요?
UI/UX 디자인 전략:
기술적 최적화 방법:
React.lazy
를 사용하여 코드를 여러 파일로 분리하고, 필요할 때만 로딩하여 초기 로딩 시간을 단축3. React에서
useState
와useReducer
를 활용한 지역 상태 관리와Context API
및 전역 상태 관리 라이브러리의 차이점을 설명하세요.useState와 useReducer: 컴포넌트 내부에서 지역 상태를 관리하는 데 사용된다.
setState
)를 통해 상태 값을 업데이트Context API: Context API는 전역 상태를 관리하는데 사용하고 상태를 직접 부모-자식 컴포넌트로 전달하지 않고 Context를 통해 공유할 수 있다. 많은 상태나 빈번한 상태 변경이 필요한 경우에서 적절하지 못할 수 있다.
useState와
와useReducer
: 상대적으로 작은 애플리케이션에서는 충분할 수 있지만, 상태가 여러 컴퍼넌트에 걸쳐 복잡하게 얽히게 되면 관리가 어려워질 수 있다.Redux나 Recoil : 애플리케이션의 상태를 중앙 집중화하여, 복잡한 상태 변경을 보다 쉽게 추적하고 관리할 수 있도록 도와준다.