항해 99/항해 6기 회고록

WIL _ 항해99 Week4 주특기 숙련(리액트) / 나만의 사전 만들기 (redux, redux-thunk, firebase, firestore)

U_D 2022. 4. 3. 15:19

1. 기간

일시 : 2022년 3월 25일 (금) ~ 2022년 3월 31일 (목)

 

2. 팀 과제

Q1. 컴포넌트 A는 리덕스 스토어를 구독하고 있습니다. 리덕스에 저장된 데이터가 변경되었을 때(A가 구독 중인 값이 변경되었다고 가정합니다.), 어떤 과정을 거쳐 컴포넌트 A가 변경된 값을 가져올 수 있는 지 흐름을 그려볼까요?

[컴포넌트 A가 변경되는 흐름]

  1. 컴포넌트에서 Action이라는 객체를 실행할시 변경된 State 값을 dispatch 해준다.
  2. 이후 redux store 내의 action 함수에서 state를 reducer로 보내준다.
  3. reducer에서 state를 변경한후 return을 해준다.
  4. return된 값을 component가 받아서 변경된다.

Q2. 옵셔널 체이닝이란 뭘까요? 어떤 경우에 사용할까요?

옵셔널 체이닝 연산자는 ES11에 도입된 새로운 연산자로 체인의 각 참조가 유효한지 명시적으로 검증하지 않고, 연결된 객체 체인 내에 깊숙이 위치한 속성 값을 읽을 수 있다. 즉, 좌항의 피연산자가 null이나 undefined일 경우 오류가 아닌 undefined를 반환한다.

 

[예시]

const adventurer = {
  name: 'chloe',
  cat: {
    name: 'joao'
  }
};

const dogName = adventurer.dog?.name;
console.log(dogName);
// expected output: undefined

위 수식을 한글로 풀면 아래와 같다. dogName = 어드벤쳐라는 객체에서 dog이라는 속성이 있으면 ? 그 안의 name이라는 값을 반환하고 만약 없다면 undefined를 반환하라

 

 

Q3. 파이어스토어에서 데이터를 가져오기까지 기다렸다가 가져오는데 성공하면 alert을 띄워 알려주려고 합니다. 어떤 방법을 써서 구현할 수 있을까요?

1) async & await

async, await 는 비동기식 콜백함수 및 Promise를 좀 더 쉽게 작성을 할 수 있습니다. async 함수는 암시적으로 Promise를 반환을 하고 await가 같이 쓰이는데 await키워드를 쓰게 되면 해당값이 반환 되기전까지 기다리는 동안 async 내부 함수는 일시 중단이 될 수 있습니다.

 

2) 비동기 방식이란?

비동기는 동시에 일어나지 않는다를 의미로 요청을 보낸 후 응답과는 상관없이 다음방식이 동작하는 방식입니다. 결과가 주어지는데 시간이 걸리더라도 그 시간 동안 다른 작업을 할 수 있으므로 자원을 효율적으로 사용할 수 있고, 비동기식 처리를 요청할 때 할일 이 끝난 후 처리결과를 알려주는 콜백이라는 함수를 함께 알려줍니다.

 

3) 동기 방식이란?

동기는 말 그대로 동시에 일어난다는 뜻으로, 요청을 보낸 후 응답을 받아야지만 다음 동작이 이루어지는 방식입니다. 이 동기방식은 어떠한 일을 처리할 동안 다른 프로그램은 정지합니다. 실제 cpu가 느려지는 것은 아니지만 요청을 하면 시간이 얼마가 걸리던지 요청한 자리에서 결과가 주어져야하기때문에 시스템의 전체적인 효율이 저하됩니다.

 

4) 동기방식과 비동기방식의 장단점

동기와 비동기는 상황에 따라서 각각의 장단점이 있습니다. 동기방식은 설계가 매우 간단하고 직관적이지만 결과가 주어질 때까지 아무것도 못하고 대기해야 하는 단점이 있고,

비동기방식은 동기보다 복잡하지만 결과가 주어지는데 시간이 걸리더라도 그 시간 동안 다른 작업을 할 수 있으므로 자원을 효율적으로 사용할 수 있는 장점이 있습니다.

 

 

Q4. <form>을 사용할 때, <button type="submit">을 함께 사용하면 리덕스 데이터가 초기화 되는 것을 볼 수 있습니다. 왜 초기화 되는 지 생각해봅시다.

 

1) submit 이벤트

HTML <button> 태그의 type 속성은 해당 버튼의 타입(type)을 명시합니다.
<button type="submit"> 
해당 버튼이 폼 데이터(form data)를 제출하는 제출 버튼(submit button)임을 명시
<button type="button"> 
해당 버튼이 클릭할 수 있는 버튼(clickable button)임을 명시
<button type="reset"> 
해당 버튼이 폼 데이터를 초기값으로 리셋하는 리셋 버튼(reset button)임을 명시
<button></button> === <button type="submit"></button>

form 태그 내에서 button을 사용할 때 타입 명시가 없다면 
기본적으로 'submit' 이벤트가 일어나게 되고,
'submit' 이벤트가 발생하면 창이 새로고침이 됩니다.
새로고침을 방지하기 위해서는 <button type="button"> 처럼 button 타입을 명시해주거나,
Event.preventDefault()를 이용하여 이벤트의 기본 동작을 실행하지 않도록 지정하면 됩니다.

const onSubmit = e => {
    e.preventDefault(); // Submit 이벤트 발생했을 때 새로고침 방지

return (
<div> <form onSubmit={onSubmit}>
      (생략) <button type="submit">등록</button>

 

Q5. 새로고침 시에도 리덕스 내의 데이터를 유지하려면 어떤 방법을 써야할까요?

[미들웨어 사용]

미들웨어는 사용하면 액션이 디스패치 된 다음, 리듀서에서 해당 액션을 받아와서 업데이트하기 전에 추가적인 작업을 할 수 있습니다.

  1. 액션을 콘솔에 출력하거나, 서버쪽에 로깅을 할 수 있습니다.
  2. 액션이 디스패치 됐을 때 이를 수정해서 리듀서에게 전달되도록 할 수 있습니다.
  3. 특정 액션이 발생했을 때 이에 기반하여 다른 액션이 발생되도록 할 수 있습니다.
  4. 특정 액션이 발생했을 때 특정 자바스크립트 함수를 실행시킬 수 있습니다.

 

 

DIY _ Q1. 리액트 상태관리

리액트 상태 관리를 어떻게 하냐에 따라 의미 없는 리렌더 등 성능 이슈가 생길 수 있고

어떤 상태 라이브러리를 쓰며 어떤 구조로 상태를 설계해서 다루냐에 따라서 유지보수 관점에서

코드의 라이프 사이클이 크게 짧아질 수도 길어 질 수도 있습니다.

 

1) 리액트 상태란?

Props 는 컴포넌트간 전달 되지만 State는 컴포넌트 안에서 관리 되고 시간이 지나면서 바뀌는 동적인 데이터입니다. State는 해당 State를 기반으로 동작되는 모든 컴포넌트의 상위 컴포넌트에 위치 되는것이 가장 바람직 합니다. 리액트 상태는 크게는 범위와 역할로 나눠 볼 수 있는데, 범위의 측면에서 본다면 State가 몇몇 컴포넌트에 국한되서 영향을 주는 지역 상태와 많은 컴포넌트에 영향을 주는 전역 상태로 나눌 수 있습니다.

 

2) 좋은 리액트 상태관리란?

State는 관련 컴포넌트들과 최대한 가까이 배치 되는게 좋습니다. State가 관련 컴포넌트와 멀어질수록 상태와 컴포넌트 사이에 있는 관련 없는 컴포넌트의 리렌더까지 일으킬 위험이 큽니다. 또, State들은 관심사에 따라 잘 분리가 되야 후에 코드 수정시 사이드 이펙트를 최소화 할 수 있습니다.

서로 관련 없는 컴포넌트들의 상태가 한번에 관리되면 결합도가 높아지게 되고 후에 어플리케이션이 비대화 될수록 의도치 않은 영향을 줄 수 있는 가능성이 높아지게 됩니다.

그리고 코드들은 격리되어 있지 않아 코드의 재사용성 또한 떨어지게 됩니다.

 

3) 전역 상태는 언제 필요할까?

다수의 컴포넌트간에 상태 의존성이 높아진다면 지역 상태로서 관리 되기 어려울 수도 있습니다. 이때 전역 상태를 이용하는것이 좋습니다.

또, 변화가 잦지 않고 서비스 전반에 걸친 상태면 전역 상태를 이용 할 수 있습니다.

 

 

DIY _ Q2. viewport

viewport란 화면 상의 화상 표시 영역을 뜻하며 다양한 디바이스가 생기면서 메타태그로 뷰를 설정할 수 있음.

즉, 다양한 디바이스에서 반응형을 하기 위한 태그로 이해할 수 있다.

  • 너비를 장치너비로 설정(많이들 사용하는 기본)
<meta name="viewport" content="width=device-width">
  • 너비를 장치 높이로 설정
<meta name="viewport" content="height=device-heght">
  • 초기 화면 배율 설정(zoom 레벨 설정) 1.0은 100%와 동일
<meta name="viewport" ontent="width=device-width, initial-scale=1.0">
  • 최소 최대 화면 배율 설정 최소 설정은 사용자가 너무 극단적으로 화면 축소하는 것을 방지함
<meta name="viewport" ontent="width=device-width, 
initial-scale=1.0, minimum-scale=1.0, maximum-scale=3.0">
  • 사용자가 크기 조절하기를 원치 않을 때
<meta name="viewport" ontent="user-scalable=no, width=device-width">

이 밖에도 반응형을 하기위해서는 가장 잘 알려진 미디어쿼리가 있어서 함께 혼재해서 많이 쓴다고 한다.

 

DIY _ Q3. redux란?

사용률이 높은 라이브러리 중에 하나로 리액트의 복잡한 컴포넌트 구조속에서 보다 간편하게 모든 컴포넌트들이 state 를 쉽게 공유할 수 있게 해주는 방식이다.

 

1)액션 (Action)

state 에 어떤 변화가 필요할 때 우린 액션이란 것을 발생시키며 이는 하나의 객체이다.

단어 그대로 어떤 동작에 대해 선언되어진 객체이다.

액션은 반드시 type 필드를 가지고 있어야 하며, 그 외의 값은 상황에 따라 넣어줄 수 있다.

 

2) 액션 생성 함수 ( Action Creator )

Action 을 생성해 실제로 객체로 만들어주는 함수이다.

 

3) 리듀서 ( Reducer )

State 에 변화를 일으키는 함수이다. 만들어진 Action 등의 일거리를 직접 수행하는 부분이다.

리듀서는 현재의 State 와 Action 을 인자로 받아 Store에 접근해 Action 에 맞춰서 State 를 변경한다.

 

4) 스토어(Store)

스토어는 현재 앱의 State 와 Reducer 함수, 그리고 몇 가지 내장 함수등을 가지고 있다.

스토어는 State 를 수시로 확인해 View 한테 변경된 사항을 알려주는 부분.

 

5) 디스패치 ( dispatch )

디스패치는 스토어의 내장 함수 중 하나로 리듀서에게 Action 을 발생하라고 시키는 것

dispatch 함수는 dispatch(action) 이런 식으로 Action 을 인자로 넘긴다.

이렇게 호출을 하면 스토어가 리듀서 함수를 실행해 리듀서 함수가 넘긴 액션을 처리해 새로운 상태를 만든다.

 

DIY _ Q4. redux-thunk란?

redux-thunk는 리덕스에서 비동기 작업을 처리 할 때 가장 많이 사용하는 미들웨어이다.

redux-thunk 를 사용하면 액션 객체가 아닌 함수를 디스패치 할 수 있다.

 

// 사용예시
const getComments = () => (dispatch, getState) => {
  // 이 안에서는 액션을 dispatch 할 수도 있고
  // getState를 사용하여 현재 상태도 조회 할 수 있습니다.
  const id = getState().post.activeId;

  // 요청이 시작했음을 알리는 액션
  dispatch({ type: 'GET_COMMENTS' });

  // 댓글을 조회하는 프로미스를 반환하는 getComments 가 있다고 가정해봅시다.
  api
    .getComments(id) // 요청을 하고
    .then(comments => dispatch({ type: 'GET_COMMENTS_SUCCESS', id, comments })) // 성공시
    .catch(e => dispatch({ type: 'GET_COMMENTS_ERROR', error: e })); // 실패시
};

//출처 : 벨로퍼트 리엑트 블로그(https://react.vlpt.us/redux-middleware/04-redux-thunk.html)

Redux-thunk 에서는 이렇게 비동기 작업 함수를 만들놓고 필요한 시점에 불러와 액션을 디스패치한다.

 

 

 

3. 개인 과제

1) 나만의 사전 완성, 2) 파이어베이스 or S3로 배포

✅ 게시글 목록 페이지

  • 게시글 목록을 화면에 그리기 (각각 뷰는 카드 뷰로 만들기)
  • 게시글 내의 예시는 파란 글씨로 보여주기
  • 게시글 목록을 리덕스에서 관리하기게시글 목록을 파이어스토어에서 가져오기

✅ 게시글 작성 페이지

 

  • 게시글 작성에 필요한 input 3개를 ref로 관리하기
  • 작성한 게시글을 리덕스 내 게시글 목록에 추가하기
  • 게시글 목록을 파이어스토어에 저장하기

✅ 추가로 해보면 좋을 기능(필수❌ )

  • 무한 스크롤 붙이기
  • 게시글 수정해보기

2) 와이어 프레임

 

3) 느낀점

과제를 진행함에 있어서 2주차 강의는 1주차 강의보다는 설명이 잘 되어 있었다.

리덕스와 파이어베이스의 흐름을 이해하는게 가장 기본인 사항인거 같고,

그 흐름을 이해하고 나서 코드의 사용법을 보면 조금 더 이해가 잘 되었다.

 

다만 하나의 기능을 만들때마다 튀어나오는 오류는.. 정말 시간을 많이 잡아먹었다.

하지만 오류가 나올때마다 오류를 위해 코드를 뜯어보니각 코드들의 의미를 더 잘 알게 되었고,파이어스토어를 가기위한 미들웨어와 리듀서의 작동을 조금이나마 짚어볼 수 있었다.

 

4) 제출

gitgub : https://github.com/U-Jinyeol/react_prac_dictionary

s3배포 : http://new-word-dict.s3-website-ap-northeast-1.amazonaws.com/

'항해 99 > 항해 6기 회고록' 카테고리의 다른 글

220610 [항해99] 수료식  (0) 2022.06.10
WIL _ 항해99(6기) Week 2알고리즘  (0) 2022.03.29
WIL _ 항해99 Week1 미니프로젝트  (0) 2022.03.13