🔮투두리스트 마무리
Event handler naming
코드를 보는데 모두 다 제각각인 핸들러의 이름을 보고
갑자기 핸들러 이름짓는 표준 정도는 존재하지 않을까 찾아봤다.
이 정도만 알아둬도 충분할 것 같다.
1. props의 경우에는 onClick처럼 on*의 접두사를 지정한다.
2. function의 경우에는 on*을 handle*로 변경하여 handleClick과 같이 사용한다.
yyyymmddhhmmss 포맷 날짜 받기
투두리스트의 아이템들의 아이디를 고유한 값으로 설정해줄 필요가 있다.
(제발 count로 1,2,3 ...로 설정하지말자)
다양한 방법이 있겠지만, 간단하게 현재의 시간값으로 설정해주고 싶어서
yyyymmddhhmmss 포맷을 리턴하는 코드를 찾아봤다.
// 10보다 작은 값에 0을 붙임
function addZero(n) {
return n < 10 ? '0' + n : n;
}
// 현재 시간을 리턴
function getCurrentDate(){
var date = new Date();
return date.getFullYear().toString() + addZero(date.getMonth() + 1) + addZero( date.getDate())
+ addZero( date.getHours() ) + addZero( date.getMinutes() ) + addZero(date.getSeconds());
}
uuid로 고유한 값 생성하기
내가 사용한 시간을 이용하는 방법은 초단위까지만 세기 때문에
1초 안에 여러 값을 만들 수 있다면 고유한 값이 더이상 아니게 되버려서
같은 아이디값을 가진 여러 아이템이 같이 동작하는 것을 보게 될 수 있다.
고유한 키 값 생성하는 것은 라이브러리를 사용하는게 마음 편하기는 하다.
uuid(universal Unique Identifier) 라이브러리를 이용해서 고유한 키값을 생성하는 걸 추천한다.
이벤트 버블링과 화살표 함수
button 컴포넌트에 달아놓은 onClick 이벤트가 계속해서 자동으로 실행된다.
무슨 일이지...?
// 변경 전
<Button color="#d32f2f" onClick={onRemove(data.id)}>
삭제
</Button>
// 변경 후
<Button color="#d32f2f" onClick={() => onRemove(data.id)}>
삭제
</Button>
이렇게 변경하니까 문제없이 잘 작동했다.
1. 콜백함수에 인자가 없는 경우
2. 일반적인 인자를 넘기는 경우
3. 이벤트 객체만 인자로 넘기는 경우
4. 이벤트 객체와 이벤트 객체가 아닌 인자를 넘기는 경우
네 가지 경우의 조금씩 다른 부분을 파악하고 가면 좋을 것 같다.
추가로 이벤트 버블링도!
LocalStorage 이용하기
새로고침하면 투두리스트들이 초기화되는 모습이 마음 한쪽을 불편하게 만들었다.
이럴때는 제일 만만한 LocalStorage를 이용해보자!
변경 전
const [todos, setTodos] = useState(mockToDo);
const handleCreate = () => {
const todo = {
id: getDate(),
title,
content,
isDone: false,
};
setTodos([...todos, todo]);
setInputs({
title: '',
content: '',
});
};
const handleRemove = (id) => {
setTodos(todos.filter((todo) => todo.id !== id));
};
const handleToggle = (id) => {
setTodos(
todos.map((todo) =>
todo.id === id ? { ...todo, isDone: !todo.isDone } : todo,
),
);
};
LocalStorage 적용 후
const [todos, setTodos] = useState([]);
const handleCreate = () => {
const todo = {
id: getDate(),
title,
content,
isDone: false,
};
const createdTodos = [...todos, todo];
saveTodos(createdTodos);
setInputs({
title: '',
content: '',
});
};
const handleRemove = (id) => {
const removedTodos = todos?.filter((todo) => todo.id !== id);
saveTodos(removedTodos);
};
const handleToggle = (id) => {
const toggledTodos = todos?.map((todo) =>
todo.id === id ? { ...todo, isDone: !todo.isDone } : todo,
);
saveTodos(toggledTodos);
};
const saveTodos = (todos) => {
localStorage.setItem(TODOS_KEY, JSON.stringify(todos));
setTodos(todos);
};
const loadTodos = () => {
const savedTodos = localStorage.getItem(TODOS_KEY);
if (savedTodos) {
const parsedTodos = JSON.parse(savedTodos);
setTodos(parsedTodos);
}
};
useEffect(() => {
loadTodos();
}, []);
localStorage에서는 데이터가 문자열 형태로만 저장되는 걸 유의해야한다.
문자열형태로 뽑혀오기 때문에 한번에 전부 저장되고 한번에 전부 불러온다.
데이터를 업데이트할 때 업데이트된 데이터를 포함한 데이터 배열 전부를 업로드해줘야 하며,
데이터를 불러올 때는 JSON.parse를 저장할 때는 JSON.Stringify를 잘 사용해주자.
추가로 localStorage에 데이터를 저장하는 부분을 커스텀훅으로 만들면 사용하기가 더 편할 것 같다.
다음 글을 참고해보자.
리액트에서 Favicon 적용하기
[react에서 favicon 적용하기]
보통 아이콘을 public 폴더에 넣어서 index에 link 태그를 이용해 적용한다.
[png to ico 변환 사이트]
다른 과금 유도없이 깔끔한 사이트. 디자인 툴이나 변환 툴 없으면 빠르게 사이트를 이용하자
[favicon size에 대한 글]
Browser favicons - 16x16
Taskbar shortcut icons – 32x32
Desktop shortcut icons – 96x96
Apple touch icons – 180x180
WordPress sizing – 512x512
브라우저 favicon을 쓸 거니까 16x16 사이즈를 사용하면 된다.
grid layout
flex-wrap의 문제점을 해결해보자.
flex-wrap을 설정해주면 다음 줄로 item이 넘어가기는 하지만 중앙정렬이 되지 않는다.
그렇다고 justify-contents로 중앙정렬을 설정해주면 다음 줄에서 시작하는 부분이 아니라 중간에서 item이 배치된다.
이도저도 아닌 아이러니한 상황
flex로는 이 문제를 해결하기는 어렵고 이러한 한계점때문에 등장한 grid를 사용해주어야 한다.
card를 배치하는 부모 컴포넌트인 CardList 컴포넌트를 display: grid로 설계한다.
const CardList = styled.div`
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, max-content));
grid-gap: 16px;
justify-content: center;
margin: 30px 0;
`;
Layout이 의도한대로 잘 나오는 것을 볼 수 있다.
코드는 stackoverflow의 정확히 같은 질문글을 참고해서 작성했다.
국내의 grid 글로는 역시나 1분코딩 사이트를 강추한다.
vercel에 배포하기
react 프로젝트를 간단하게 배포하려면 vercel 사이트를 추천한다.
github repo를 추가해준뒤
main branch에 push만 해주면 자동으로 몇초안에 배포를 해준다.
정말 프로그래밍하기 좋은 시대에 살고 있다는 걸 느낀다.
문득 시대 별 개발자 밈이 생각난다.
예외처리는 꼭 하자
const handleCreate = () => {
// 변경 전
const todo = {
id: getDate(),
title,
content,
isDone: false,
};
const createdTodos = [...todos, todo];
saveTodos(createdTodos);
setInputs({
title: '',
content: '',
});
// 변경 후
if (title && content) {
const todo = {
id: getDate(),
title,
content,
isDone: false,
};
const createdTodos = [...todos, todo];
saveTodos(createdTodos);
setInputs({
title: '',
content: '',
});
} else {
alert('입력값을 올바르게 입력해주세요.');
}
};
input에 값이 입력하지 않으면 create를 해주면 안되는데 그냥 create해버리는 사태가 발생했다.
헐레벌떡 발견하자마자 수정해주었다.
예외처리는 필수적으로 꼭꼭 해주자!!!
그리고 나말고 다른 사람한테 테스트도 시켜보면 너무 좋다.
'개발일기' 카테고리의 다른 글
[TIL] 결국 쓰러졌습니다 (4) | 2022.12.02 |
---|---|
[TIL] 하루가 너무 짧다구요 (0) | 2022.12.01 |
[TIL] 한번만 쓰고 버린다구요? (4) | 2022.11.29 |
[TIL] 졌잘싸 (0) | 2022.11.28 |
[TIL] 성불하게 해주세요 (1) | 2022.11.26 |