[항해99] Week 5 [7.18 - 7.23]

Hajun Song·2022년 7월 24일
0

Weekly I Learned

목록 보기
5/7
post-thumbnail

[항해99] Week 5 [7.18 - 7.23]

0. ✅심화 - 미니프로젝트 사전준비

심화주차. 주어진 강의를 보지는 않았다. 너무 방대했다.
그렇게 바로 과제를 시작하며 필요한 것들을 찾아나가는 방식으로 진행했다.
새로운 적용들. 회원가입, 로그인, 업로드, 데이터 관리.
여름이었다..

🐱‍💻Note
세상과 맞서 싸울 준비물. 지식의 검.
어느것 하나도 쉬운게 없었다.
하지만 지식의 검 구글과 함께라면 이어나갈 수 있음을 깨달았다.

0-0. ✅심화주차 개인과제

로그인 사용자용 사이트를 만들어라.
숙련주차 개인 과제를 통해 게시글 작성을 만들 수 있게 되었다.
그렇게 바로 심화주차 개인과제로 밀어붙여졌다. 쉴 틈? 있을리 없다.
그것이 스파르타니까. (끄덕)

💡항해가 제공한 개인 과제 달성목표

"로그인 사용자용 매거진 사이트 만들기"

  • 파이어베이스 Auth를 이용해 회원가입, 로그인 기능을 만들 수 있어요.
  • 파이어스토어를 사용해 데이터 입력, 수정, 삭제, 읽기를 만들 수 있어요.
  • 게시글 마다 타입을 지정해 해당 타입 별로 다른 레이아웃을 보여줄 수 있어요.

지난 주차와 마찬가지로 주제는 상관없었다.
다녀온 여행지에 대해 위치와 사진 그리고 이야기를 받아 작성하는 페이지를 만들고자 했다.
뜻대로 될리가 없다.

주어진 과제 조건들과 별개로 게시글 작성시 미리보기에 초점을 두며 작업했다.

심화주차 개인과제 보러가기

🐱‍💻Note
우린 하나야.
스프링팀의 참여로 게시글 데이터를 직접 안짜고 어렵지 않게 쌓을 수 있었다.
지식만큼이나 사람이 남는 일정들.

0-1. 과제 성찰의 시간

모자랐던 부분..

#0. 다른사람이 댓글과 게시글을 작성시 새로고침을 눌러야 업데이트가 됨

  • 사용자A가 게시글을 작성하면 리덕스 스토어에 업로드가 되므로 리랜더가 됨.
  • 타인B가 게시글을 작성하는 경우 직접적으로 웹의 버튼을 누른게 아니기 때문에 데이터베이스의 내용은 바뀌지만 사용자A의 리덕스 스토어가 바뀌지 않게 됨.
  • 그러므로 사용자 A는 새로고침을 하지 않는 이상 업데이트가 되지 않음.

예상 해결방안

0-1.

  • setInterval, setTimeout을 이용한 무지성 리랜더링
    Too many re-renders.
    React limits the number of renders to prevent an infinite loop.
    ➡사용법 미숙으로 실패. 불필요한 api 접근횟수 무지성 증가.

0-2.

  • 댓글 작성 당시의 최신 데이터를 가져와 리덕스 스토어에 업로드 feat @cslim0527
    ➡양뱡향 통신 구현 전 최선의 방법

0-3.

  • 👍양방향 통신 socket 공부하기
    다음 기회엔 제대로 적용해보기. 더 나은 나로.

#1. 새로고침시 자동으로 로그아웃 됨 ( 코딩 미숙 )

  • 새로고침 혹은 창을 닫을 시 로그아웃 됨.
  • 하지만 필요에 따라 필요한 제공되는 기능일 뿐.
    흔한 메신저에서 로그아웃 잘하자와 같은 현상을 걱정하지 않아도 됨.

해결방안

0-1.

양호했던 부분..

#0.미리보기와 업로드를 나누어 진행.

미리보기까지 storage를 사용할 필요는 없기 때문.

  • 미리보기 기능을 만들기 위해서는 참조할 url이 필요하다.
  • 업로드 후에는 서버상 이미지의 url이 필수적이다.
  • 하지만 미리보기는 사용자 컴퓨터의 가상 path도 문제가 없다.
function onFileChange(e) {
    ...
    let ProfilePic = e.target.files;
    setSignUpProfilePicture([...ProfilePic]);
    const reader = new FileReader();
    reader.readAsDataURL(ProfilePic[0]);
    reader.onload = (e) => {
      setSignUpProfilePicturePreview(e.target.result);
    };
  }
  • 미리보기 이미지는 사용자 컴퓨터의 가상 path로 특별한 데이터 이동 없이 사용.
  • signUpProfilePicture에 파일을 업로드 할 준비만 해 둠.
const submitSignUp = async (e) => {
    e.preventDefault();
    ...
    const ImagesRef = ref(
      storage,
      `users/${SignUpName}:&^@${signUpProfilePicture[0].name}`
    );
    await uploadBytes(ImagesRef, signUpProfilePicture[0]).then(() => {
      console.log("Uploaded file!");
    });
    await getDownloadURL(ImagesRef).then((url) => {
      SignUpPic = url;
    });
  ...//회원가입 실패시 catch문 내부
      deleteObject(ImagesRef)
        .then(() => {})
        .catch((err) => {
          alert(err.message.substring(10));
        });
      window.scrollTo(0, 0);
  };

0-1. 여기서 예상되는 문제.

업로드 해야하는 이미지가 커지면 발생하는 문제.
위 경우 업로드 버튼 이후에 업로드를 시작하므로 사용자 입장에서 await 시간이 지루해짐.

  • file이 바뀌는 순간 미리보기 파일로 업로드 시작
    ➡ 게시글 작성을 취소하거나 사진 수정시 중지 혹은 삭제하고 다시 시작
    ...서버비 없어요
  • 업로드 중 스피너 사용
    ➡ 엘리베이터의 거울은 그렇게 설치되었다. 관련 기사
  • 👍파일 사이즈 제한
    ➡ 현재 3MB 제한 적용 중.
    ➡ 이미지 압축도 도전해보기.
    다음 기회엔 제대로 적용해보기. 더 나은 나로.
function onFileChange(e) {
  ...
 const correctForm = /(.*?)\.(jpg|jpeg|png|gif|bmp)$/;
    if (e.target.files[0].size > 3 * 1024 * 1024) {
      inputImage.current.innerText = "파일 사이즈는 3MB까지만 가능합니다.";
      return;
    } else if (!e.target.files[0].name.match(correctForm)) {
      inputImage.current.innerText = "이미지 파일만 업로드 가능합니다.";
      return;
    }
  ...
}

🐱‍💻Note
더 나은 나로.
지금 당장 다음 미니프로젝트에 치여 지나간 것들의 아쉬운 부분들을 넘김이 아쉽다.
하지만 다음에 만나면 얄짤없다. 다음 기회엔 제대로 적용해보기. 더 나은 나로.

0-2. ✅심화주차 회고

지난 주 적은 내용처럼 항해 시리즈를 놓으니 마음이 조금은 편해졌다.
여유있게 더 성장을 하고, 배운 것들은 간단하게 카드형식으로 올리고.
조금씩 조금씩 성장하는 법을 배워가고 있다.

CamelCase를 연습하면서 변수명의 디테일이 중요함을 느끼고 있다.
그동안에는 그냥 image라고 지어왔다.

  • 어떤 이미지?
    postImage로 지어보니 내가 붙인 변수의 대상을 알기가 더 쉬워졌다.
  • 그 이미지의 무엇?
    postImageInputRef로 지어보니 내가 붙인 변수의 특징을 알기가 더 쉬워졌다.

🐱‍💻Note
내일의 나는 남이다.
길어도 자동완성이 되는 세상이다.
짧은 것 보단. 남이 읽고 이해할 수 있는 코드가 좋은게 아닐까.


1. 🔍AXIOS

6주차. 미니 프로젝트가 시작되었다. 이제부턴 협업이다.
파이어베이스의 서버리스 서비스로 이루어지던 것들을 잠시 내려놓는다.
이제부터는 스프링팀이 준비하는 API를 사용 가능해야 진행이 된다.

지나간 Ajax

그동안 0주차와 1주차에서 API를 사용하기 위해 Ajax라는 기술을 사용했다.
type을 정하고 url을 알려주고 data를 쥐어주어 심부름을 시켰다.
성공하면 가져온 것으로. 실패하면 실패한 것으로 가공해서 사용했다.

function post_article() {
        let article = $('#article').val()
        let today = new Date();
        let date = today.toLocaleString()
        let team = window.location.href.split('team/')[1].split('/')[0]

        $.ajax({
            type: "POST",
            url: '/team/write',
            data: {article_give: article, date_give: date, team_give: team},
            success: function (response) {
                alert(response["msg"])
                show_notice();
                $('#article').val('')
            }
        });
    }

대충 이런 코드를 썼던 기억이 난다.

이제는 Axios

공식 문서를 읽고나서 대충 느낀점은.. 그렇다.
Ajax라는 개념을 구현한 함수. 라이브러리.

Axios도 사용법에 있어서 별로 차이가 없었다.

1-0. 🔍설치 및 적용하기

yarn add axios
import axios from 'axios';

1-1. 🔍Axios 사용법

1-1-0. 기본 사용법

axios('/user/12345');

Axios는 기본적으로 아무런 method를 정해주지 않으면 Get 요청을 실시한다.
이때 url 제공은 필수이다.

1-1-1. 메서드 사용법

그 외의 기능들은 method 지정을 통해 사용 가능하다.

axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});

메서드는 get, delete, post, put, patch 등이 있다.

💡 요청을 만드는데 사용 가능한 config.
Axios 공식문서 - 요청 Config

1-1-2. 메서드 명령어 사용법

위의 방식은 너무 길다.
Axios는 편의를 위해 지원하는 모든 요청 메소드의 명령어를 제공한다.

axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.options(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])

예를 들면 아래의 코드와 같다.

axios.post('/user/12345', {firstName: 'Fred',lastName: 'Flintstone'})

1-2. 🔍Axios 응답 확인

요청을 할 수 있게 되었으면 응답을 받을 수 있어야 한다.

1-2-0. 요청에 대한 응답 받기

요청 이후 then을 이용해 응답받은 값을 다뤄주면 된다.

axios('/user/12345').then((response) => console.log(response));

1-2-1. 응답의 구성요소

response 즉, 요청에 대한 응답에는 다음과 같은 내용들이 담겨있다.

{
  // `data`는 서버가 제공하는 응답.
  data: {},

  // `status`는 HTTP 상태 코드.
  status: 200,

  // `statusText`는 HTTP 상태 메시지.
  statusText: 'OK',

  // `headers`는 HTTP 헤더.
  // 모든 헤더 이름은 소문자, 괄호 표기법을 사용하여 접근.
  // 예시: `response.headers['content-type']`
  headers: {},

  // `config`는 요청을 위해 `Axios`가 제공하는 구성.
  config: {},

  // `request`는 이번 응답으로 생성된 요청.
  // 이것은 node.js에서 마지막 ClientRequest 인스턴스.
  // 브라우저에서는 XMLHttpRequest.
  request: {}
}

한 번 쯤은 무지성으로 부딪혀보는 것도 중요하다.
아래와 같이 사용 및 확인 가능하다.

axios.get('/user/12345')
  .then(function (response) {
    console.log(response.data);
    console.log(response.status);
    console.log(response.statusText);
    console.log(response.headers);
    console.log(response.config);
  });

1-3. 🔍Axios 인스턴스

API에 제공되는 요청이 길어질 수록 꼴보기 싫다.

axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});

이럴때 자주 사용하는 요청의 configdefaults로 미리 지정해 줄 수 있다.
바로 Axios instance 이다.

1-2-0. 인스턴스 생성방법

인스턴스는 create를 통해 생성한다.
생성에 제공하는 값들은 config 양식에 맞추어야 한다.
인스턴트 생성시 해당 값은 defaults로 지정된다.

💡 요청을 만드는데 사용 가능한 config.
Axios 공식문서 - 요청 Config

const instance = axios.create({
  baseURL: 'https://some-domain.com/api',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});

1-2-1. 인스턴스 활용법

이후 선언한 instance를 이용해 API 요청을 실시 할 수 있다.
이때 위 instance의 defaults와 요청의 config결합되어 전달된다.
다음은 위에서 정의한 instance를 사용한 예시이다.

instance.get('/longRequest', {
  timeout: 5000
});

이는 아래의 요청과 같다.

axios({
  method: 'get',
  url:'https://some-domain.com/api/longRequest',
  headers: {'X-Custom-Header': 'foobar'},
  timeout: 5000		//Config는 우선 순위에 따라 병합된다.
});  

💡 Config는 우선 순위에 따라 병합됩니다. lib/defaults.js 라이브러리에서의 기본값, 인스턴스의 defaults 속성, 요청의 config 인자를 순서대로 찾습니다. 후자가 전자보다 우선순위가 높습니다.

Axios 공식문서

🐱‍💻Note
새로운 배움은 언제나 환영이야!
새로운 배움은 늘 어렵다. 어려움이 익숙해지는 것은 즐겁다.


2. ✅내가 아는 것(22.7.24.)

점점 배움을 이어가는 시간들 속에서 내가 아는 것들을 정리할 필요가 생겼다.
책의 내용이 아니라 책 그 자체도 정리가 필요하다.
괜히 도서관에 사서가 필요한게 아니다.

🐱‍💻Note
책을 정리해두지 않으면 도서관이 아니라 창고가 된다.


범례
⏺ 사용가능
⏫ 빠르게 성장중
🔼 성장중
🔽 기억에서 삭제중
⏬ 다뤄본 경험 있음

🔼 HTML, CSS, Javascript

⏫ React

├react-route-dom
│ ➡ // yarn add react-router-dom
├react-redux
│ ➡ // yarn add redux react-redux
├react-bootstrap
│ ➡ // yarn add react-bootstrap bootstrap
│		└import "bootstrap/dist/css/bootstrap.min.css";
├react-fontawesome
│ ➡ // yarn add @fortawesome/fontawesome-svg-core
│ ➡ // yarn add @fortawesome/free-solid-svg-icons
│ ➡ // yarn add @fortawesome/react-fontawesome
├react-typed
│ ➡ // yarn add react-typed
└styled-components
  ➡ // yarn add styled-components
+ firebase
	├firestore
    ├Storage
    └Auth
  ➡ // yarn add firebase

🔽 Python

├flask
│	└jinja2
├pymongo
└bs4

⏬ C#

├GEANT4
└Unity

⏺ AWS

├S3
└EC2

3. ✅미니 프로젝트에 들어가며

주특기 리엑트의 기초, 숙련, 심화주차를 모두 마무리했다.
쉴 틈 없이 달렸고, 아직 절반도 못왔다.
그렇게 미니프로젝트에 다시 던져졌다.

미니프로젝트 기획 변천사

🐱‍👤TODO
말하기 듣기 쓰기
초등학교부터 이어져 내려오는 최고의 학습법, 말하기 듣기 쓰기 + 읽기.
미니프로젝트 기간 동안 지금까지 배운것 꼼꼼하게 적용하며 정리하기

profile
일단 똥을 싸라, 그리고 박수칠 때 까지 닦아라.

0개의 댓글