📌 Literal Type
타입 지정시 string, number 같은 원시타입만 할당할 수 있는 것이 아니다.
개발자가 지정한 글자나 숫자 들을 타입으로 지정할 수 있다.
1 | let john: "Texas"; |
- 이제 john에는 ‘Texas’라는 글자만 할당될 수 있고 kim에는 33이라는 숫자만 할당될 수 있다.
타입 지정시 string, number 같은 원시타입만 할당할 수 있는 것이 아니다.
개발자가 지정한 글자나 숫자 들을 타입으로 지정할 수 있다.
1 | let john: "Texas"; |
1 | type Animal = string | number; |
1 | type NumOut = (x: number, y: number) => number; |
1 | useEffect(effectCallback); |
함수 컴포넌트에서 발생 가능한 side-effect(부수효과)를 관리하기 위해 사용한다.
리액트가 할 수 없는 작업을 할 때, useEffect()
를 사용한다.
리액트 Hook의 실행흐름은 위 사진과 같다.
함수 컴포넌트에서 클래스 컴포넌트의 생명주기를 구현하기 위해 useEffect()
가 componentDidMount()
, componentDidUpdate()
, componentWillUnmount()
메서드가 발생되는 주기를 대체할 수 있어야한다.
useEffect()가 이들을 100% 대체할 순 없지만 문제없을 정도로 흉내내어 사용하고 있다.
componentDidMount()
대체 방법1 | useEffect(() => { |
componentDidUpdate()
대체 방법1 | useEffect( |
componentWillUnmount()
대체 방법이벤트 구독/취소처럼 컴포넌트가 제거될 때 실행되어야 하는 함수의 경우 다음과 같이 사용한다.
1 | function Tester() { |
cleanUp
함수는 메모리 누수 방지를 위해 UI에서 컴포넌트를 제거하기 직전에 수행된다.이는 componentWillUnmount()
처럼 동작하는 것 같지만, 리액트 팀은 클래스 컴포넌트 생명주기대로 로직을 구현했을 때, 대규모 프로젝트에서 버그를 많이 발견하였다.
그리하여 리액트 팀에서는 구독취소 후 다시 구독하는 과정을 통해 이를 구현하였다.
1 | useEffect(() => { |
1 | const [stateValue, stateUpdater] = useState(initState); |
함수 컴포넌트에서 상태를 관리할 때 사용하는 API이다.
stateUpdater
는 보통 setStateValue
이런식으로 set을 붙혀서 사용한다.initState
값은 초기 렌더링 시에만 사용되는 값으로, 이후 렌더링 시에는 무시된다. 만약 초깃값을 계산하는데 많은 시간이 필요한 경우 콜백함수를 통해 지연된 초기화 처리가 가능하다.
1 | const [stateValue, stateUpdater] = useState(() => { |
updateState
함수는 setState
함수처럼 객체 상태를 관리하기 합성된 객체를 반환해야 한다.
1 | const [state, updateState] = useState({ |
updateState
함수는 상태 병합이 아닌 대체를 하므로 변경되지 않는 객체 값을 유지하기 위해서 위와 같이 해야한다.리액트 Hook은 클래스로 컴포넌트를 만들 때 발생하는 문제점을 해결하기 위해 등장하였다.
모든 JavaScript는 TypeScript이지만,
1 | interface State { |
위 예시를 설명하면, 앞서 말한 모든 타입스크립트가 자바스크립트다
JavaScript는 동적 타입만을 제공하여 예측하기 어려운 타입변환으로 디버깅이 어려워지는 문제점이 있어 이를 해결하고자 TypeScript가 탄생하였다.
TypeScript는 정적 타입 시스템을 사용하여 코드가 실행되기 전에 코드에 대하여 예측해준다.
계속 읽기1 | import styled from "styled-components"; |
Link 컴포넌트 안에다가 styled-component를 생성하고 as props를 전달해주었다.
위와 같이 할 경우, as props에 img 태그가 들어오게 된다면
이를 해결하기 위해 조건부 렌더링을 해주었다.
1 | import styled from "styled-components"; |
문제의 원인은 npm 명령어로 webpack server만 실행시켰는데, webpack config.js
파일에 static
속성값을 [build]
로 주었기 때문에 정적 이미지 파일을 불러오기 위해서는 build
폴더에서 assets
을 찾는다.
그러므로 npm run build
명령어로 build 폴더를 생성한 후 그 안에다가 img를 넣어주고 경로를 설정해주어 해결하였다.
1 | <Link |
aria-label
속성 있을 때, 조건부로 css 추가 이 속성을 삭제한 이유는 span 태그를 사용하여 Link 컴포넌트를 구현하였을 때, role="link"
로 해주었기 때문에 aria-label
속성을 굳이 해주지 않아도 되므로 삭제하였다.
로또 게임 기능을 구현해야 한다. 로또 게임은 아래와 같은 규칙으로 진행된다.
1 | - 로또 번호의 숫자 범위는 1~45까지이다. |
1 | 14000 |
1 | 1,2,3,4,5,6 |
1 | 7 |
1 | 8개를 구매했습니다. |
1 | 3개 일치 (5,000원) - 1개 |
1 | 총 수익률은 62.5%입니다. |
1 | [ERROR] 로또 번호는 1부터 45 사이의 숫자여야 합니다. |
1 | 구입금액을 입력해 주세요. |
1 | const app = new App(); |
1 | const numbers = MissionUtils.Random.pickUniqueNumbersInRange(1, 45, 6); |
1 | class Lotto { |
score 객체에 3등 4등 5등 의 키 값은 숫자로만 주었는데, bonus 등수는 문자열로 주어서 출력시 5등 4등 3등 2등 1등 Bonus등수가 출력되어서 이를 해결하기 위해 score의 key 값을 문자열로 변경하였다.
lotto 배열의 요소도 [1, 2, 3, 4, 5, 6] 이런 형태의 배열인데, print 결과물이 “[1, 2, 3, 4, 5, 6]” 이렇게 나와야 하므로 이에 대한 처리를 해주었다.
1 | this.Lotto.forEach((lotto) => MissionUtils.Console.print(`${lotto}`)); |
1 | this.Lotto.forEach((lotto) => MissionUtils.Console.print(`[${lotto}]`)); |
1 | this.Lotto.forEach((lotto) => |
Number.prototype.toLocaleString()
메서드를 사용하면 천단위에 ,를 찍은 문자열로 변환한다.1 | class Lotto { |
1 | // 내 코드 |
1 | class Lotto { |
1 | class Lotto { |
1 | // 리팩터링 전 |
2주차때 클래스구조와 테스트에 대해서 조금은 익숙해져서 3주차 미션을 받았을 때 구조가 비슷하여 조금 마음이 놓였다.
jest expect
함수와 matcher
함수를 찾아보면서 단위 테스트 기능에 대해 공부해볼 수 있는 기회여서 좋았다.리액트 컴포넌트에 전달되는 Prop(속성)의 Type(타입)을 검사하는 방법에 대해 알아보자.
1 | EmotionCard.propTypes = { |
위와 같이 직접 custom propTypes를 통해 prop를 검사할 수 있지만 리액트 팀에서 제공하는 propTypes 패키지를 사용하면 편리하고 안정적으로 prop 검사를 할 수 있다.
1 | npm i -D prop-types |
1 | import PropTypes from "prop-types"; |
1 | import { objectOf, number } from "prop-types"; |
propTypes.objectOf
는 객체의 속성 값이 모두 동일한 타입을 설명할 경우 사용한다.1 | import { shape, arrayOf, string } from "prop-types"; |
propTypes.shape
는 객체의 각 속성별 타입을 설명할 때 사용한다.arrayOf
를 사용하였다.객체의 속성이 정확히 동일하게 일치해야한다면
propTypes.exact() 를 사용한다.
propTypes는 null 타입 체크를 할 수 없어 oneOf를 사용한다.
1 | import { oneOf, oneOfType, shape, string } from "prop-types"; |
PropTypes.oneOf([’grow’, ‘learn’, ‘connect’])
이 중 하나만 파라미터로 들어올 수 있다.함수에 기본값을 주듯이 props에 기본값을 주는 것을
1 | import React from 'react'; |
author.bio
author.job