-
Notifications
You must be signed in to change notification settings - Fork 8
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주차] 고윤정 미션 제출합니다. #2
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.
안녕하세요 윤정 님~!
리뷰하다 보니 뭔가 일주일 만에 엄청나게 성장하신 것 같은데요?! 코드 가독성도 좋아지고 고심하여 코드를 작성하신 게 느껴졌습니다! 🤝 이번주 과제도 고생하셨습니다!! 👍🏻
@@ -10,6 +10,9 @@ | |||
"preview": "vite preview" | |||
}, | |||
"dependencies": { | |||
"@emotion/react": "^11.13.3", | |||
"normalize.css": "^8.0.1", |
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.
오 normalize
좋습니다!
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.
오? normalize.css
는 처음봐서 찾아보니 정규화를 시켜주고 다른 브라우저로 보더라도 일정한 디자인을 볼 수 있도록 해주기위해서 사용한다고 하는데 좋은거 알아갑니다!!!
@@ -1,5 +1,85 @@ | |||
/** @jsxImportSource @emotion/react */ | |||
import { css } from '@emotion/react'; | |||
import 'normalize.css'; |
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.
전역적으로 스타일을 적용하고 싶다면 Emotion의 Global
컴포넌트도 사용해 보세요!
참고 자료 - Emotion Global Styles
const bodyStyle = css` | ||
margin: 0; | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
height: 100vh; | ||
background-image: linear-gradient( | ||
to bottom right, | ||
rgb(247, 196, 218), | ||
rgb(239, 239, 239) | ||
); | ||
`; |
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.
스타일 코드는 컴포넌트(App
) 바깥에 작성해 주시면 가독성이 더 좋아질 것 같아요 😀
export default function App() {
// 생략
}
const wrapper = css`
// 생략
`;
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.
뺄지 말지 고민했던 부분 중 하나인데 확실하게 말씀해주셔서 좋아요ㅎ 당장 밖으로 빼겠습니다🫡
// 초기 상태를 localStorage에서 불러옴 | ||
const [todoList, setTodoList] = useState(() => { | ||
const savedTodoList = localStorage.getItem('todoList'); | ||
return savedTodoList ? JSON.parse(savedTodoList) : []; | ||
}); |
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.
오 엄청 간결하면서도 동작이 잘 보여요!!
이름을 엄청 잘 지으시는 것 같어요
}, [todoList]); | ||
|
||
return ( | ||
<div className="body" css={bodyStyle}> |
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 AddTodoList = todoList.concat({ | ||
id: todoList.length, | ||
text, | ||
checked: false, | ||
}); | ||
setTodoList(AddTodoList); |
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.
concat
메서드 사용 좋습니다! spread
연산자도 활용해 봅시다!
const AddTodoList = todoList.concat({ | |
id: todoList.length, | |
text, | |
checked: false, | |
}); | |
setTodoList(AddTodoList); | |
setTodoList(prev => [ | |
...prev, | |
{ | |
id: todoList.length, | |
text, | |
checked: false, | |
}, | |
]); |
} | ||
|
||
// props 값 검증 | ||
InputBox.propTypes = { |
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.
나중에 타입스크립트도 잘하실 것 같아요 😉
// 항목 삭제 | ||
function onDelete(id) { | ||
// 주어진 id와 일치하지 않는 항목들만 남김(일치하면 필터링 -> 해당 항목 삭제) | ||
const updatedTodoList = todoList.filter((todoItem) => todoItem.id !== id); |
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.
👍🏻👍🏻
<span | ||
className="span" | ||
// 완료 여부에 따라 스타일 변경 | ||
css={todoItem.checked ? spanCheckedStyle : spanStyle} |
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.
동적 스타일링까지 아주 좋습니다!!
@font-face { | ||
font-family: 'LINESeedKR-Rg'; | ||
src: url('https://fastly.jsdelivr.net/gh/projectnoonnu/[email protected]/LINESeedKR-Rg.woff2') | ||
format('woff2'); | ||
font-weight: 400; | ||
font-style: normal; | ||
} |
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.
normalize.css
를 비롯하여 이렇게 @font-face
를 정의하는 부분도 글로벌 스타일로 적용해 보시면 좋을 것 같아요!
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주차 미션에서 윤정님의 코드 리뷰를 맡게 된 심여은입니다!
깔끔하고 귀여운 스타일과 props의 타입까지 체크하는 꼼꼼한 코드 잘 읽어 보았습니다! 저는 styled-component의 방식으로 작성했는데, 윤정님은 emotion의 css()를 잘 적용해 주신 것 같아요!
저도 이번에 state와 props 사용이 어렵다고 느꼈는데, 같이 공식문서 읽어보면서 성장해봐요~~!!
<div className="container" css={containerStyle}> | ||
<h2 className="title" css={mainTitleStyle}> |
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.
emotion을 잘 적용해 주셔서 코드가 매우 간결하네요!
// + 버튼 클릭(form 제출) | ||
function onClickButton() { | ||
// 공백 입력 방지 | ||
if (text.trim() === '') return; |
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.
캬.. 공백 방지까지...디테일의 은혜가 끝이 없군요
todoList: PropTypes.arrayOf( | ||
PropTypes.shape({ | ||
id: PropTypes.number.isRequired, | ||
text: PropTypes.string.isRequired, | ||
}).isRequired | ||
), | ||
setTodoList: PropTypes.func.isRequired, | ||
}; |
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.
오 props 값을 이렇게 검증할 수 있군요! 새로 알아갑니다👀
setTodoList(AddTodoList); | ||
|
||
setText(''); // input 값 초기화 | ||
inputRef.current.focus(); // 버튼 누른 후에도 input box에 자동 포커싱 |
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.
useRef를 이용해서 input에 포커스를 주는 부분 새롭게 알아갑니다👀👀
&::-webkit-scrollbar { | ||
// 스크롤바 모양 변경 | ||
width: 4px; | ||
} | ||
&::-webkit-scrollbar-thumb { | ||
border-radius: 2px; // 스크롤바 모서리 둥글게 | ||
background: rgb(255, 238, 245); // 스크롤바 색상 변경 |
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 AddTodoList = todoList.concat({ | ||
id: todoList.length, | ||
text, | ||
checked: 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.
TodoList 배열 안의 객체를 식별하는 id를 length로 주신 이유가 있을까요? 만약 id가 같다면 원하지 않는 다른 객체가 수정될 수 있을 것 같아요! Date.now()
와 같이 중복되지 않는 값을 id에 할당하면 좋을 것 같습니다!
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.
윤정님 그냥 화면만 봐도 깔끔 정갈 큐티입니다. 역시나 코드도 잘 정돈되어 있군요...!!!
제가 아이디어나 하고 싶은 기능을 쏟아내는 것은 잘하는데 깔끔하게 정리하고 효율적으로 사용하는것은 잘못하는데...많이 배우고 갑니다.. 최고...🩷
@@ -10,6 +10,9 @@ | |||
"preview": "vite preview" | |||
}, | |||
"dependencies": { | |||
"@emotion/react": "^11.13.3", | |||
"normalize.css": "^8.0.1", |
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.
오? normalize.css
는 처음봐서 찾아보니 정규화를 시켜주고 다른 브라우저로 보더라도 일정한 디자인을 볼 수 있도록 해주기위해서 사용한다고 하는데 좋은거 알아갑니다!!!
// 초기 상태를 localStorage에서 불러옴 | ||
const [todoList, setTodoList] = useState(() => { | ||
const savedTodoList = localStorage.getItem('todoList'); | ||
return savedTodoList ? JSON.parse(savedTodoList) : []; | ||
}); |
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.
오 엄청 간결하면서도 동작이 잘 보여요!!
이름을 엄청 잘 지으시는 것 같어요
@@ -42,7 +42,7 @@ export default function InputBox({ todoList, setTodoList }) { | |||
} | |||
`; | |||
|
|||
const [text, setText] = useState(''); | |||
const [text, setText] = useState(''); // input에 입력한 값 | |||
const inputRef = useRef(null); |
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.
저는 form을 사용하지 않아서 form을 사용했을 때 새로고침을 방지해야하는군요!! 배워갑니다!!!
// + 버튼 클릭(form 제출) | ||
function onClickButton() { | ||
// 공백 입력 방지 | ||
if (text.trim() === '') return; |
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.
캬.. 공백 방지까지...디테일의 은혜가 끝이 없군요
@@ -79,8 +83,9 @@ export default function InputBox({ todoList, setTodoList }) { | |||
ref={inputRef} | |||
className="input-box" | |||
placeholder="할일을 입력하세요" |
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.
이런 placeholder하나만으로도 이 사이트의 정체성을 보여주는 것 같아요. 🦖 친절한 사이트...
const liStyle = css` | ||
margin: 3px 0px 3px 0px; | ||
`; | ||
|
||
const checkBoxStyle = css` |
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.
이렇게 체크박스까지 디테일을 놓치지 않는 것이 디자인적으로 완성도가 매우 높은 것 같습니다.👍🏻
안녕하세요! LG U+ 유레카 프론트엔드 1기 고윤정입니다.
React로 미션을 진행함에 있어 걱정이 많았는데 어찌저찌 끝냈네요..🤣 바닐라JS로 만들었던 투두리스트를 React로 다시 개발해보니 확실히 차이점이 눈에 보였습니다. React에 익숙하지 않았을 땐 HTML, CSS, JS 파일을 따로 나눠서 관리하는게 더 편하다고 생각했는데 이번 미션을 진행해보니 마크업과 렌더링 로직이 같은 위치에 있는게 더 관리하기 쉽고 편리하다는 걸 느꼈습니다. 여기서 사람들이 React를 사용하는 이유를 확 깨달았던 것 같아요!
공식문서를 읽으며 React와 더 친해지도록 하겠습니다 화이팅+_+ !
📎 알게 된 부분
css()
함수 사용📎 개선하고 싶은 부분
📎 Key Questions
지난주 미션과 비교했을 때, React로 구현하는 과정에서 어떤 점이 더 편리하거나 복잡했나요?
React의 Virtual DOM(가상 돔)이란 무엇이고, 이를 사용했을 때의 장점은 무엇이 있나요?
React에서 state와 props는 무엇이고 어떻게 사용하나요?
setState()
를 사용하여 값을 변경React에서 컴포넌트를 분리하는 기준은 무엇일까요?
📎 배포
https://jejukyj-react-todo.vercel.app/
