-
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
[2주차] 김철흥 미션 제출합니다. #3
base: main
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.
캘린더도 직접 구현하시고 타입스크립트로 과제 하시느라 수고하셨습니다! 디자인도 열심히 구상하신 것 같아요 2주차 과제 고생 많으셨습니다!
import leftArrow from '@/assets/left-arrow.svg?react'; | ||
import rightArrow from '@/assets/right-arrow.svg?react'; | ||
|
||
export const LeftArrowIcon = styled(leftArrow)` | ||
width: 1.8rem; | ||
height: fit-content; | ||
`; | ||
|
||
export const RightArrowIcon = styled(rightArrow)` | ||
width: 1.8rem; | ||
height: fit-content; | ||
`; |
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.
왼쪽 화살표와 오른쪽 화살표에 두 개의 이미지를 사용하는 것보다 rotate(180deg)를 해서 하나의 이미지만 사용해도 좋을 것 같습니다!
<S.DayListSection> | ||
<S.DayList> | ||
{DAY_LIST.map((day, index) => ( | ||
<S.DayListItem key={index}>{day}</S.DayListItem> |
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.
key에 index값을 넣는 것은 권장되지 않습니다. 아래 문서 참고하시면 좋을 것 같아요!
e.preventDefault(); | ||
|
||
if (task.trim() === '') { | ||
alert('할 일을 입력해주세요!'); |
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.
alert는 확인 버튼을 누르기 전까지 사용자의 다른 입력을 막아 사용성을 저해하기 때문에 modal을 사용하는 것을 추천드립니다!
<Postit paperColor="#DDEBF1"> | ||
<S.DoneHeader> | ||
<S.DoneTitleSection> | ||
<S.DoneTitle>Done</S.DoneTitle> | ||
<DoneIcon /> | ||
</S.DoneTitleSection> | ||
<TaskCount taskCount={doneList.length} isDone={true} /> | ||
</S.DoneHeader> | ||
|
||
<TaskList tasks={doneList} /> | ||
</Postit> |
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.
<S.TaskEditInput | ||
type="text" | ||
value={editedContent} | ||
onChange={handleContentChange} | ||
$isEditing={isEditing} | ||
autoFocus | ||
/> |
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.
수정 가능하게 만들어두신 거 좋은 것 같아요 👍👍
@media (max-width: 1440px) { | ||
align-items: center; | ||
} | ||
|
||
@media (max-width: 1024px) { | ||
flex-direction: column; | ||
padding: 6rem 3.2rem; | ||
} |
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 Postit = ({ children, paperColor }: PostItProps): JSX.Element => { | ||
return ( | ||
<S.PostitWrapper> | ||
<PostitPaper $paperColor={paperColor} /> |
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.
이미지가 깨질때나 스크린 리더를 사용하는 사용자를 고려하여 이미지 태그 사용하실 때는 alt 속성을 추가하는 것이 좋습니다!
https://www.tcpschool.com/html-tag-attrs/img-alt
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.
캘린더 직접 구현하신거 대단합니다,,
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.
캘린더가 디자인 적이에요 이걸 직접 구현하셧다니 엄지 두개 드릴게요 👍👍
저랑 코드 스타일이 엄청 다른거 같아서 훨씬 배울점이 많은 것 같아요!!
import { generateCalendar } from '@/utils/generateCalender'; | ||
import { formatDate } from '@/utils/formatDate'; | ||
|
||
import * as S from './Calendar.styled'; |
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.
이렇게 스타일 구현할 수 있다는 걸 처음 알았습니다... 신기하네용
year: new Date().getFullYear(), | ||
month: new Date().getMonth() + 1, | ||
day: new Date().getDate(), |
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.
Date 객체를 새로 계속 생성하기보다 어디에 today 값을 설정해서 한번만 불러오는게 어떨까용?
const handleDaySelect = (day: string) => { | ||
setSelectedDate(day); | ||
}; |
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.
이 정도의 함수는 onClick 안에서 처리할 수 있으면 좋을 것 같습니당
onClick={()=>setSelectedDate(day.FullDate)} 이런 느낌??
const handleEditClick = () => { | ||
setIsEditing(true); | ||
}; | ||
|
||
const handleCancelClick = () => { | ||
setIsEditing(false); | ||
}; |
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.
마찬가지로 함수를 따로 빼는 것 보다 인라인으로 적는게 코드 수나 가독성 쪽에서 좋을 것 같습니당
=> 함수가 여러번 재사용 되거나 useMemo, CallBack등을 사용해야할 때는 따로 빼는 것이 좋습니다!
undefined | ||
); | ||
|
||
export const useTasks = () => { |
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.
개인적으로 Context를 쓰는 부분은 파일명이나 함수명을 useTaskContext로 써봐도 좋을 것 같아요
const selectedDateTask = useMemo( | ||
() => tasksByDate[selectedDate] ?? [], | ||
[tasksByDate, selectedDate] | ||
); | ||
|
||
const toDoList = useMemo( | ||
() => selectedDateTask.filter((task) => !task.completed), | ||
[selectedDateTask] | ||
); | ||
const doneList = useMemo( | ||
() => selectedDateTask.filter((task) => task.completed), | ||
[selectedDateTask] | ||
); |
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.
이정도의 계산은 그냥 일반 변수로 해도 될 것 같다는 생각이 있습니당
오히려 불필요한 메모지에이션으로 복잡성만 늘릴 수도 있어요
🔗 Deploy URL
To Do List
🫥 느낀 점
🤷🏼♂️
KQ 1. Virtual-DOM과 사용시의 이점
Virtual-DOM 이란?
실제 DOM(Document Object Model)을 바로 업데이트하지 않고 메모리에 가상으로 DOM 트리를 생성하여 관리하는 DOM 형식
사용 시의 이점
KQ 2.
React.memo()
,useMemo()
,useCallback()
함수로 진행할 수 있는 렌더링 최적화✅ React.memo()
함수형 컴포넌트를 memoization(메모이제이션)하여, props가 변경되지 않으면 재렌더링하지 않음
일반적인 PureComponent의 함수형 컴포넌트 버전이라고 볼 수 있음
컴포넌트가 불필요하게 렌더링되지 않아 성능이 좋아집니디만, props가 많거나 복잡한 경우에 주의 깊게 사용해야 합니다.
✅ useMemo()
값(value)을 메모이제이션하기 위한 Hook으로, 특정 값이 변경될 때만 값이 다시 계산됨
연산 비용이 큰 값이나 객체가 불필요하게 재생성되지 않도록 하여 성능을 최적화할 수 있음
✅ useCallback()
함수를 메모이제이션하기 위한 Hook으로, 특정 의존성 배열(dependency array)의 값이 변경되지 않으면 이전에 저장된 동일한 함수 인스턴스를 반환함
📌 자식 컴포넌트에 콜백 함수를 전달할 때 불필요한 재렌더링을 방지하는데 특히 유용함
KQ 3. React 컴포넌트 생명주기
React 컴포넌트는 생성 → 업데이트 → 소멸 단계를 거침
1. 컴포넌트 마운트(Mount)
: 컴포넌트가 처음 화면에 나타날 때 실행
빈 배열 []을 의존성 배열로 넘기면 처음 한 번만 실행됨
ex.) API 요청, 이벤트 리스너 등록
2. 컴포넌트 업데이트(Update)
: 상태(state)나 props가 변경될 때마다 실행됨
someValue
가 바뀔 때만 실행됨(여러 상태를 넣으면 각각의 변화에 따라 실행됨)
3. 컴포넌트 언마운트(Unmount)
: 컴포넌트가 사라질 때(clean-up) 실행
주로 타이머 제거, 이벤트 리스너 해제, 구독 해제 등에 사용
🔁 전체 구조 예시