---
# System prepended metadata

title: Dream Coding - React 10. Business Card Maker - Coding Challenge

---

# Dream Coding - React 10. Business Card Maker - Coding Challenge
## ==10.2 로그인 화면 Firebase 추가==

### Firebase

- 웹 어플리케이션에 sdk를 추가할땐 (vanila형식이 아닌) npm 이나 yarn등을 이용해서 추가해주면 된다.
ex) `yarn add firebase`

### Vscode

- 폴더 안에 하나의 폴더만 있을경우 하단식구조로 보이지 않음
⇒ setting에서 `Compact Folders` 로 설정을 바꿀 수 있음
- 원하는 줄로 가기 ctrl+P :n


## ==10.5 Route로 화면 전환==

### React `Router`

- API들을  자세하게 살펴보기
    - Hook
        - `useHistory`
    - Method
        - `BrowserRouter`
        - `Switch`
        - `Route`

### Firebase

- User 라는 uid를 불러오기 때문에

```jsx
history.push({
pathname : '/maker',
state: {id : userID},
});
```

아이디를 저장소에 불러온다.

`onAuthStateChanged` 

- 로그인한 사용자에 대한 정보가 필요한 앱 페이지마다 전역 인증 객체에 관찰자를 연결 / 사용자의 로그인 상태가 변경될 때마다 이 관찰자가 호출됨
- **`onAuthStateChanged`** 메서드를 사용해 관찰자를 연결 / 사용자가 로그인되면 관찰자에서 사용자에 대한 정보를 가져올 수 있다

## ==10.8 10.9 Maker 레이아웃 작업==

### 함수의 분리

- Component와 직접적으로 상관없는 함수(모듈) 들은 분리하도록 하자
- 유지보수에도 편하고, Component가 오직 View만 담당할 수 있게 된다.


## ==10.11 Maker EditForm==

- **ref 연결할 때 Tip (VSC tip)**

     `**alt**` 키 누르고 단어들 선택

    → `**alt**` 누른 상태에서 **`shift`** 방향키로 단어별 선택 후 복사 → 다중선택으로 붙여넣기

## ==10.14 10.15 State 업데이트하기==

### `setState`를 전달할때의 유의점

- 상위 컴포넌트에서 바로 전달하지 말것. 최소한 anonymous function등으로 묶어서 보낼것

```jsx
<Foo
	onChangeListener={()=>{setState();}}
/>
```

- 하위 컴포넌트에서도 되도록 바로 쓰지 말고, 자체 function에 할당해서 사용할 것

```jsx
function Foo(onChangeListener){
	const goo=()=>{
		onChangeListener();
	};
}
```

## ==10.17 이미지 업로드 - Dependency Injection==


### Tip for Dependency Injection

- 단순히 class 나 img 를 전달하는 것보다, 해당 자료를 확실히 **사용할 Component를 넘기는것**이 확장성에 더 좋을 수 있음
    - 결과론적으로는 컴포넌트를 컴포넌트로 한 차례 더 감싸게 됨
    - 이때 Component에 props를 전달함으로써 확장성과 유지보수성 향상에 기여할 수 있음

    ```jsx
    // index.js
    class Foo {}
    const fooInstance = new Foo();
    ```

    ```jsx
    // good code -> Component 전달
    const fooComponent = () => (
    	<FooUsingComponent foo={fooInstance}/>
    )
    ReactDOM.render(
    	<React.StrictMode>
    		<App FooComponent={FooComponent} />
    	</React.StrictMode>,
    );
    ```

    ```jsx
    // better code -> 확장성 좋게 props를 받는 Component 전달
    const fooComponent = (props) => (
    	<FooUsingComponent {...props} foo={fooInstance}/>
    )
    ReactDOM.render(
    	<React.StrictMode>
    		<App FooComponent={FooComponent} />
    	</React.StrictMode>,
    );
    ```

## ==10.24 프로젝트 마무리 하는 법 (firebase 정리, useEffect 중요한 포인트)==


### 프로젝트 마무리 하는 방법

1. 검증 (QA) 
2. 디자인이 정확한지
3. `console.log` 는 지워줌
4. warning은 정리해줌
5. 코드 개선점이 있는지
6. 보안
7. 성능 개선점이 있는지
8. 필요한 Analytic (분석툴)이 충분히 갖춰줬는지 ⇒ 성능 개선점에 충분한 지점이 될 수 있음
9. 배포를 어떤 식으로 진행할 것인지 ⇒ **A/B 테스트 (그룹을 나눠서 테스팅)**

### 라이브러리를 쓸 때의 팁!

- 일단 공식문서를 확인한다
- 그 다음, class를 직접 들어가서, 어떤 interface로 구현되어 있는지, 어떤 method들이 포함되어 있는지 확인하는 습관을 들이는 것이 좋다.

### 모르는 타입이 올 경우 (특히 `switch`문을 쓸때 `default` 경우로)

- Error를 던져 주는 것이 좋다.

### Firebase import

- firebase를 통으로 import 할 필요가 없다.
  app 안의 app이라는 작은 인터페이스를 불러와서 필요한 부분만 활용한다.


# 기술별 정리

## ==HTML==

### 구조적인 요소를 위한 태그들 (non-semantic tag vs semantic tag)

[HTML Semantic Elements](https://www.w3schools.com/html/html5_semantic_elements.asp)

[HTML5의 구조적인 요소들 #2 - ,](https://webclub.tistory.com/268)

- non-semantic tag : 단순 **스타일링만이 목적**일 경우 씀
    - ex) `<div>` `<span>`
- semantic tag : 브라우져와 사용자가 명확한 의미를 가지게 되는 태그들 (**SEO이슈**)
    - ex ) `<article>` `<form>` `<header>` `<section>`

### `form`

[나의 첫 HTML 폼](https://developer.mozilla.org/ko/docs/Learn/HTML/Forms/Your_first_HTML_form)

[form event(폼 이벤트 타입) & 문서로딩](https://webclub.tistory.com/342)

- **사용자와 웹사이트간에 데이터를 전송**하기 위한 공간을 마련하는 DOM
    - 즉, **폼에 의해 수집된 데이터는 서버로 전송된다** 라는 걸 전제로 깔고 있음
- 주요 attribute
    - `action` : 데이터를 보낼 **URL**
    - `method` : 어떤 **HTTP 방식**을 사용할 것인지 ( GET , POST 등의 REST API)
- 주요 JS method
    - `reset()` : form 에 들어간 모든 사용자 입력을 깨끗이 원래 상태로 되돌림
- form 에 자주 들어가는 HTML DOM
    - `label` `input` `textarea` `button`
- form 에 적용되는 이벤트
    - `submit` : 서버로 전송하는 명령인 submit에 적용
    - `change` : 컨트롤의 값이 변경되었을때 발생함
                 `input`(text,radio,checkbox)`textarea` `select` 에만 적용

### `textarea`

[- HTML: Hypertext Markup Language | MDN](https://developer.mozilla.org/ko/docs/Web/HTML/Element/textarea)

- 멀티라인 일반 텍스트 편집 컨트롤을 나타냄
- 즉 여러줄의 긴 문장을 입력할 수 있음
- `form` 안에서 자주 사용되며, **댓글이나 리뷰**등을 받기 위해서 사용된다.

### `input`

[: 입력 요소](https://developer.mozilla.org/ko/docs/Web/HTML/Element/Input)

- **다양한 방식**으로 사용자로부터 입력을 받아올 수 있음 ⇒ `form` 안에서 자주 사용됨
    - `type` 을 지정함으로써, 동작 방식을 지정가능
    - 대표적인 type
        - button : 버튼
        - checkbox : 체크박스
        - text : 기본적인 text
        - submit : 제출하는 버튼
        - select : 선택지를 주고 그중 1개를 고르는 양식
    - 기존 html DOM 가 아예 겹치는 것도 있음 (`button` `select` 등이 대표적)
    ⇒ 어떤 것을 쓰는게 더 좋은지 확인해보고 사용하길 권장
- input 의 `type` 및 `name` 을 정하는 건 꽤나 중요함. 
브라우져가 **자동완성을 추천해줄때 사용되기 때문**
- 그 외에 중요한  attribute
    - `placeholder` : 양식이 비어있을때 **미리 나타내주는 내용**
    - `value` : **양식의 현재 값 
                  →** 실시간으로 클라이언트에서 업데이트를 해야할때 자주 사용
                  → 이 경우 `change` 이벤트 리스너와 같이 많이 사용된다.

## ==CSS==

### `linear-gradient()`

[linear-gradient](https://developer.mozilla.org/ko/docs/Web/CSS/linear-gradient())

- 두 개 이상의 색이 직선을 따라 **점진적으로 변화하는 이미지**를 생성

### `pseudo-element`

- `::before` `::after` 등은 **border 에 구분선을 넣는 효과를 대신해서 쓸 수도 있다**.

### `outline`

[outline](https://developer.mozilla.org/ko/docs/Web/CSS/outline)

- 모든 외곽선 속성을 한꺼번에 지정
    - **border보다도 더 바깥 외곽선**을 지정
    - 결과적으로 CSS **box-model** 은 다음과 같음 (통상적으로는 outline을 box-model에 비포함)

    ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/4fcc85e8-cf26-431d-92e5-a380d57624e6/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/4fcc85e8-cf26-431d-92e5-a380d57624e6/Untitled.png)

- 차례로 `outline-color` `outline-style` `outline-width` 를 포함 (즉 `outline` 아 축약형 표현)

### `overflow`

[overflow](https://developer.mozilla.org/ko/docs/Web/CSS/overflow)

- 요소의 콘텐츠가 너무 커서 요소의 블록 서식( block, inline 등) 맥락에 맞출 수 없을때의 **처리법**
- 반드시 `height` 가 설정되어 있거나 `white-space` 의 값을 `nowrap` 으로 설정해야함
- 자주 쓰는 value
    - `visible` (default) : 내용이 더 길어도 그대로 보임
    - `hidden` : 내용이 넘치면 자름 (자른 부분은 보이지 않음)

           ( hidden 이후에 ... 을 붙여주고 클릭시에 visible로 변경)

    - `scroll` : 콘텐츠를 잘라내고 스크롤 할 수 있게 함 (항상 스크롤바가 보임)
    - `auto` : 내용이 잘릴 때만 스크롤 바가 보임

### `animation` 그리고 `@keyframes`

[CSS 애니메이션(Animation), 키프레임(keyframes)](https://webclub.tistory.com/621)

- `animation` : 요소에 적용된 CSS 스타일을 다른 CSS 스타일로 부드럽게 전환시켜줌
    - `transition` 보다 훨씬 규모가 크고 복잡하며, 다양한 능력을 가지고 있음
    - ex) `animation : spin 2s linear infinite;`
- `animation` 의 장점
    1. JS를 모르더라도 애니메이션 생성 가능
    2. JS를 이용한 애니메이션은 잘 만들어졌더라도 성능이 좋지 못할때가 있음. CSS animation은 frame-skipping 같은 여러 기술을 활용하여 최대한 부드럽게 렌더링됨
    3. 브라우저가 애니메이션의 성능을 효율적으로 최적화할 수 있음
- `@keyframes` : 어떤 모양에서 어떤 모양으로 변할지 정의할 수 있음
    - `animation` 의 첫번째 인자로 넘겨주면 됨

## ==JavaScript==

### `innerText` vs `textContent`

[https://stackoverflow.com/questions/35213147/difference-between-textcontent-vs-innertext](https://stackoverflow.com/questions/35213147/difference-between-textcontent-vs-innertext)

- `innerText` ⇒ non-standard / `textContent` ⇒ standard
- `innerText` ⇒ **visible only**  / `textContent` ⇒ **full text (visible 유무 상관 X)**
- `innerText` ⇒ HTMLElement 에 정의 / `textContent` ⇒ Node에 정의 ****

### Array vs Object (성능)

- state를 업데이트를 할때, 매번 `Array.map` 을 이용하여 `O(n)` 으로 수행하면 성능에 영향을 줄 수 있음
    - 특히 현재 문제사항과 같이 form에서 실시간으로 state로 업데이트를 한다면 성능에 큰 영향을 줌
- Object는 Array와 달리, element에 `O(1)` 에 접근할 수 있음
    - 또 index signature를 이용한다면, `O(1)`에 element를 추가할 수 도 있음
    - 이를 이용하여 성능을 향상시킬 수 있음

### `Object.keys(obj)` `Object.values(obj)` `Object.entries(obj)`

- 일반 객체 (`Object`) 의 메서드
- 전부 **배열을 return** 한다.
    - `Object.keys(obj)` : obj안에 있는 key값들의 배열
    - `Object.values(obj)` : obj안에 있는 value값들의 배열
    - `Object.entries(obj)` : obj안에 있는 [key,value] 값들의 배열

### `delete` 연산자

- **객체의 속성을 제거**

```jsx
const Employee = {
  firstname: 'John',
  lastname: 'Doe'
};
delete Employee.firstname; 
console.log(Employee.firstname); // undefined
```

### `Event.currentTarget` vs `Event.target`

[JavaScript | event target과 currentTarget의 차이점](https://velog.io/@edie_ko/JavaScript-event-target%EA%B3%BC-currentTarget%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90)

- `Event.currentTarget` ⇒ **이벤트 리스너가 붙어있는 DOM을 통째로 반환**
- `Event.target` ⇒ **이벤트를 발생시키는 자식 DOM을 반환**
- **이벤트 버블링** 을 찾아보면 무슨 말인지 이해 될것

### `input` 에서 파일 업로드

[웹 어플리케이션에서 파일 사용하기](https://developer.mozilla.org/ko/docs/Web/API/File/Using_files_from_web_applications)

- input에 `change` 이벤트를 붙임으로써, **File의 객체**를 가져올 수 있음
    - 이 File의 객체의 key 값은 number 이므로, 가져온 파일중 1개만 사용하고 싶다면 다음과 같이 작성하면 됨

    ```jsx
    const selectedFile = document.getElementById('input').files[0];
    ```

### 내장 Interface : `FormData()`

[FormData](https://developer.mozilla.org/ko/docs/Web/API/FormData)

## ==React==

### `useCallback()` `useEffect()` `useMemo()`

- 두개의 Hook 모두 두번째 인자로 dependency를 **넘겨주는 편이 바람직**

    ⇒ 조건부로 재할당을 할 수 있게 하기 위함

- 두번째 인자를 넘겨주지 않음 ⇒ 매번 렌더링시에 재실행
- 빈 배열을 넘겨줌 ⇒ `onMount()` 와 같은 효과. 첫 렌더링시에만 실행해서 메모리 보존
- 배열에 인자를 넣어서 넘겨줌 ⇒ 렌더링시에 해당 인자가 shallow comparison 을 통해 다르다면 실행

### Hook의 성능??

- **Component가 반드시 필요한 리렌더링만을 진행하는가?**
- **렌더링이 발생한다면, property 및 method가 반드시 필요한 것만 재할당 할 수 있게 하는가?**
- **위의 2가지를 무시할 만큼, 렌더링이 자주하는가? (따라서 메모리를 할당하면서 위의 2가지를 지키지 않아도 되는가?)**

⇒ 이 3가지 사항이 React가 View Library로서 성능을 최적화에 관여

### `setState` 주의점

- `setState` 는 오래된 스테이트를 가지고 있을 수 있음
    - realTimeDB는 변경이 되어져 있지만, `state`는 최신화가 되지 않은 경우가 있을 수 있기 때문
- 이 경우 기존 card를 최신화하는 것이 아닌, realTimeDB에서 state를 가져와 최신화를 시켜준뒤 state에 반영함
    - 이때, `setState`의 인자로 콜백함수를 넘겨주는 편이 코드 가독성에 좋음

```jsx
setCard(cards =>{
    const updated = {...cards};
    update[new] = {~~};
    return updated;
});
```

### 배열 컴포넌트
- `uid` (key) 를 설정할때 해당 컴포넌트를 생성하는 **시간(**`Date.now()`)을 이용하는것은 꽤 좋은 solution
    - 단, 사용자로부터 입력을 받아서 생성하는 것에 한정함
    - props를 통해 배열 컴포넌트를 생성하는 경우, 시간은 그렇게 좋지 못한 solution이 될 수 있음(너무 빠르게 생성이 되니깐)