오늘의 도전과 배움
평소보다 +10분 정도 늦게 일어나서 하드트레이닝에서 비몽사몽 vite 배우고, 일찍 씻고 점심 먹고 1시 좀 넘어서 클린코드 계속 만들고 친구들이랑 고라니교 디코방 만들고 드림코딩 리액트 강의 들었다! 그리고 쉬엄쉬엄 react-payments 만료일이 잘못 구현된 걸 확인 후 input에서 숫자랑 특수기호 막는 거를 만드는데 정규식을 잘 몰라서 11시 40분에 디코에 자몽님이랑 수다 떨 겸 들어가서 옐님이랑 같이 하다 안 돼서 토끼님과 미량님께 도움을 구해서 해결했다....!!!
궁금하거나 어려웠던 점
정규 표현식, storybook 기초, vite vitest 차이? 모르는 것과 낯선 것 중 어떤 상태인지 알기엔 아직 모르는 것들이 많기 때문에 다 어렵다ㅜㅎ
내일 해보고 싶은 것들
useRef를 사용하지 않고 id를 사용해서 각각의 input들을 컴포넌트로 분리했을 때 useRef, forwardRef를 사용하지 않아도 돼서 편리했다.
최적화 성능 용량 등,, 걱정하지 않기. 리액트를 쓰는 것 자체가 이미 용량이 큰 것임
더 나은 커밋 메시지를 작성하기 위한 Git 커밋 메시지 템플릿
1.26 오전 12시에 해결한 정규식 코드...!
const CreateCard = ({ goToPage }) => {
const [inputs, setInputs] = useState({...});
...
function handleInputChange(validate, nextElemId) {
return e => {
const { name, value, pattern } = e.target;
const onlyText = text => {
const pattern = /[0-9]|[ \[\]{}()<>?|`~!@#$%^&*-_+=,.;:\"'\\]/g;
// pattern으로 text를 test한다
return !pattern.test(text);
};
if (pattern && !RegExp(pattern).test(value)) {
// 패턴이 있고 통과하지 못하면
return;
}
// 쓰는곳이랑 가까이
const isNumberText = text => !isNaN(text);
if (name === 'username') {
// 영어랑 한글만
if (!onlyText(value)) return;
} else {
// 숫자만
if (!isNumberText(value)) return;
}
// 띄어쓰기 막기 아직.
setInputs(prev => ({
...prev,
[name]: value,
password: {
...prev.password,
[name]: value,
},
}));
const nextElem = document.getElementById(nextElemId);
if (validate(value)) {
nextElem.focus();
}
};
}
...
어떤 툴을 공통적으로 이용하길래 자동화된 툴이 생겼을까?
eject
yarn eject
숨겨져있는 유용한 툴들을 열어보기 단 다시 포장할 수 없음
정말 필요해서 무엇을 세부적으로 수정해야 할 때
웹팩 바벨 설정을 몰라도 많이 설정되어져 쓰는 것들을 쉽게 프로젝트를 만들어 쓸 수 있지만, 현업에서는 추가적으로 이것저것 설정해야 되는 것들이 있어서 create-react-app을 잘 이용하지 않고 수동적으로 관리함.
=> eject를 할 일은 거의 없고 바벨, 테스팅 관련된 것들, 타입스크립트, eslint, jest, postCSS, webpack 이런 아이들이 많이 사용되어지는구나.
babel이나 webpack 별도 설정?
Babel, WebPack, EsLint를 공부 한다는것은 개발자가 스스로 배포관련 된것을 상세하게 조정할 수 있도록 configuration 해서 쓸 수 있도록 하는건데요.
저는 필요할때 필요한 부분을 찾아서 설정을 바꾸거나, 구글링으로도 충분하다고 생각해요. 팀이나 프로젝트의 규모가 커지면 이부분을 담당하는 팀이 따로 있어서 개별 개발자가 설정할 일이 없거든요 :)
VSCode extension - Reactjs code snippets, Auto Import
프론트엔드 유용한 익스텐션: https://youtu.be/bS9yTI2fC0w
여기 영상에서 추가로 하나더 알려드렸어요: https://youtu.be/m7wsrVQsVjI
주석색깔 바꾸는 방법은: https://youtu.be/2UaKfAz-eEI
flex box vs grid
https://webdesign.tutsplus.com/articles/flexbox-vs-css-grid-which-should-you-use--cms-30184
플렉스 박스와 그리드는 구현하고자 하는 디자인에 따라 선택해서 써야 해요.
실제 대부분의 모든 디자인은 플렉스 박스로 구현이 가능한데, 정말 그리드 형태의 디자인은 (특히 두가지 이상의 셀들이 병합되어있는 경우) 그리드를 이용해야 해요 :)
public에는 static(정적)한 HTML, 이미지, 리소스 등 변하지 않는 아이들
src(소스)에는 동적으로 변화되는 다이나믹한 소스 코드들, 자바스크립트 코드 아이들이
들어감.
확장자를 .js로 작성하면 순수 자바스크립트 클래스 등의 파일들이 헷갈리므로, 구분하기 위해 .jsx 를 쓰기!
리액트 컴포넌트구나. 자바스크립트 로직이 들어있는 아이구나.
프로젝트 복사 cp -R test habit-tracker
StrictMode 조금 더 엄격한 모드로 코딩
코딩하다 실수하거나 위험한 사항들이 발생하면 에러 메시지가 표기됨
배포된 버전에는 활성화 되지 않음
데모용: https://dream-coding-academy.github.io/react_basic_habit_tracker/
크롬 React Developer Tools (디버깅 툴)에 표시되지 않는 것? 리액트 컴포넌트가 아닌 순수 HTML 요소구나!
state(컴포넌트상태) props(부모로부터) 다 확인 가능
HTML은 마크업 언어이고 JSX는 엄밀히 말하면 자바스크립트 코드임. 나중에 바벨이 HTML, JS로 변환
// 처음 리액트
return React.createElement('h1', {}, 'Hello!');
->
return <h1>Hello!</h1>
// 다른점
<div class="" onclick=""></div>
-> jsx
<div className='' onClick={}></div>
// 한 개 이상의 자식 노드는 묶어야 됨. div(쓸데없는낭비) -> Fragment
// ul, ol 등의 의미있는 태그는 그대로
return (
<>
<h1></h1>
<div></div>
</>
);
// jsx에서는 자바스크립트 코드로 비즈니스 로직 작성 가능
return (
<>
<div>{user ? `hello ${user}` : 'not user'}<div>
<ul>
{['a', 'b'].map(item => (
<li key={item}>{item}</li>
))}
</ul>
</>
);
Introducing JSX: https://reactjs.org/docs/introducing-jsx.html
JSX In Depth: https://reactjs.org/docs/jsx-in-depth.html
https://vitejs.dev/
https://vitejs-kr.github.io/guide/
tdd에서는 항상 실패하는 테스트를 작성함!
에러가 났을 때의 테스트 케이스도 작성해보기. 에러를 던지게 할 때는 expect에 함수를 넣어줘야 함
테스트는 문제가 없는 것 같은데 에러가? 코드를 보기. 코드는 문제가 없는데 에러면 테스트 코드를.. 교차적으로 검증하기
"devDependencies": {
"@vitest/ui": "^0.2.1",
"vite": "^2.7.13",
"vitest": "^0.2.1
}
// currency.js
//원래는 서버
const currencyRateDict = {
'Dollar': 1400,
'Yen': 10.49,
}
// 케이스가 여러 개..! => '일반화'된 구현
export function toWon({currency, amount}, fromCurrency){
if(currency !== fromCurrency){
throw Error(currency + `는 ${fromCurrency}가 아닙니다!`)
}
return { currency: 'Won', amount: currencyRate * amount};
}
export function fromDollarToWon({currency, amount}){
if(currency !== 'dollar'){
throw Error(currency + "는 dollar가 아닙니다!")
}
return { currency: 'won', amount: 1400 * amount};
}
//
export function fromDollarToWn(from) {
return toWon(from, 'Dollar');
}
// currency.text.js
import { describe, it, expect } from 'vitest';
import { toWon, fromDollarToWon } from './currency.js';
// api 에서 의존하는 값이 들어온다 (내가 모르는 값)
// 내가 아는 것... 어떤 모양의 어떤 값이 들어올지는 안다
// 어떤 값이 왔다고 가정하고... 그 뒤에 계산 로직!
describe('currency rate', ()=>{
describe('fromDollarToWon', () => {
it('1달러 당 1400원일 때, 10달러는 14000원이어야 한다', ()=>{
expect(fromDollarToWon({ currency: 'dollar', amount: 1 }))
.toEqual({ currency: 'won', amount: 1400 });
expect(fromDollarToWon({ currency: 'dollar', amount: 10 }))
.toEqual({ currency: 'won', amount: 14000 });
})
it('yen 엔을 넣으면 fromDollarToWon은 에러를 던진다', ()=>{
expect(()=>fromDollarToWon({ currency: 'yen', amount: 10 }))
.toThrowError('yen는 dollar가 아닙니다!');
})
})
describe('toWon', () => {
it('', () => {
expect(toWon({}))
})
})
})