# 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이 될 수 있음(너무 빠르게 생성이 되니깐)