FE RYAN
완벽하지 않으면 어때
FE RYAN
전체 방문자
오늘
어제

블로그 메뉴

  • 💾 깃허브 링크
  • 홈
  • 태그
  • 분류 전체보기 (151)
    • 개인프로젝트 (8)
      • 개인 포트폴리오 웹앱 (6)
      • 프론트엔드 기술면접 아카이빙 웹앱 (2)
    • 기록 (121)
      • 원티드 프리온보딩 인턴십 (0)
      • 코드스테이츠 프론트엔드 (75)
      • 생각들 (3)
      • Today I learned (32)
      • 회고 (9)
      • 리뷰 (1)
    • 개발 (17)
      • React (3)
      • Javascript (7)
      • CSS (1)
      • HTML (3)
      • HTTP (1)
      • 자료구조 (0)
      • 알고리즘 (2)
    • 코딩테스트 (2)
      • 백준 (2)
      • 프로그래머스 (0)
    • 디자인 (1)
      • UI & UX (1)
    • 수학 (0)
    • 자기계발 (0)

공지사항

인기 글

태그

  • ES6
  • useMemo
  • 리액트
  • seb39
  • 원시타입
  • 회고
  • 메인프로젝트
  • HTML
  • 딥다이브
  • seb 39
  • 자바스크립트
  • 프론트엔드
  • 코드스테이츠
  • 부트캠프
  • Til
  • css
  • 포트폴리오
  • 타입스크립트
  • 신입개발자
  • 자바스크립트 딥다이브

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
FE RYAN

완벽하지 않으면 어때

기록/코드스테이츠 프론트엔드

12주 2일차 - 웹 접근성, 서버 복습

2022. 7. 12. 23:27
728x90

12주 2일차 - 웹 접근성, 서버 복습

1. 배운 것

  • jsx 내에서 label태그의 for 속성은 htmlFor 로 써야 한다. for는 반복문이라서.
  • 몽고디비 콜렉션, 모델, 스키마
  • 클라이언트의 수정내용을 서버에도 반영하려면 build 다시 해준다.
  • drop database가 안되는 경우 권한 설정 문제이다. 몽고디비 아틀라스 홈페이지에서 security 탭으로 가서 권한 변경하기.

2. 내용 정리

useEffect 복습

어떠한 상태(state)의 값이 바뀌었을때 동작할 함수를 작성할 수 있다.

  • 첫번째 인자 콜백함수: 가장 처음에 앱이 실행될 때의 첫 렌더링 또는 state변경 후 재렌더링 종료시 실행됨.
  • 두번째 인자 Dependency Array: 의존성 배열이다. 첫번째 매개변수인 함수가 두번째 매개변수인 의존성 배열의 값이 변경될 때만 실행되게 제한함. 생략 가능하며 생략시 모든 렌더링 때마다 함수가 실행됨.
  • 의존성 배열이 빈 배열이면 함수를 최초 렌더링 시 1번만 실행.

Axios 방식 CORS 이슈 해결 - 1. 클라이언트

// client > src > component > List.js

import React, { useState, useEffect } from 'react';
import styled from 'styled-components';
import axios from 'axios';

const StyledList = styled.ul`
  > li {
    list-style: none;
    margin-bottom: 10px;
    border-bottom: 0.5px solid #6f6f6f;
  }
`;

const List = ({ contentList }) => {
  useEffect(() => {
    axios
      .post('/api/test')
      .then(response => {
        // 성공 핸들링
        alert('요청 성공');
        console.log(response);
      })
      .catch(error => {
        // 에러 핸들링
        alert('요청 실패');
        console.log(error);
      });
  }, []);
  return (
    <>
      {contentList.length !== 0 ? (
        <StyledList>
          {contentList.map((el, idx) => (
            <li key={idx}>제목:{el}</li>
          ))}
        </StyledList>
      ) : null}
    </>
  );
};

export default List;
  1. 경로를 client 폴더로 하여 axios 설치.
  2. Component > List.js
    1. 비동기 코드 처리를 위해 useEffect import하기
    2. axios도 import 하기
    3. 함수 컴포넌트 리턴문 이전에 useEffect 함수 넣기
    4. useEffect 콜백함수 내부에서 axios post 요청 코드 넣기
  3. 프록시 설정 (참고 https://create-react-app.dev/docs/proxying-api-requests-in-development/#configuring-the-proxy-manually)
// client > src > setupProxy.js 새 파일 생성

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    '/api',
    createProxyMiddleware({
      target: '<http://localhost:5000>',
      changeOrigin: true,
    })
  );
};

404 오류 : 클라이언트랑 서버의 포트 번호가 달라서 발생. 프록시 설정으로 해결한다.

Axios 방식 CORS 이슈 해결 - 2. 서버

클라이언트의 post요청을 처리할 코드를 추가.

app.post('/api/test', (req, res) => {
  console.log(req);
  res.status(200).json({ success: true });
});

서버에서 응답으로 보내는 json데이터를 클라이언트에서 받기

  • 클라이언트에서 접근하는 방법: response.data.프로퍼티key
  • 서버에서 보내는 방법: res.status(200).json({ key: value })

서버 코드

// 서버 코드에서 응답으로 보내는 json객체의 데이터 클라이언트에서 받기
// response.data.success = true
// response.data.text = 'hi'

// 1. 서버 코드
app.post('/api/test', (req, res) => {
  // console.log(req);
  res.status(200).json({ success: true, text: 'hi' });
});

클라이언트 코드

// 2. 클라이언트 코드
// useEffect 훅 내부에서 state를 서버의 응답 데이터 값으로 변경.

const List = ({ contentList }) => {
  const [text, setText] = useState('');

  useEffect(() => {
    axios
      .post('/api/test')
      .then(response => {
        // 성공 핸들링
        alert('요청 성공');
        setText(response.data.text);
      })
      .catch(error => {
        // 에러 핸들링
        alert('요청 실패');
        console.log(error);
      });
  }, []);
  return (
    <>
      <h3>{text}</h3>
      {contentList.length !== 0 ? (
        <StyledList>
          {contentList.map((el, idx) => (
            <li key={idx}>제목:{el}</li>
          ))}
        </StyledList>
      ) : null}
    </>
  );
};

클라이언트에서 서버로 데이터 보내기

const body = {
    author: 'Ryan',
  }; // 서버로 보낼 데이터인 body 객체 생성

useEffect(() => {
    axios
      .post('/api/test', body) // post의 2번째 인수로 보냄.
      .then(response => {
        // 성공 핸들링
        alert('요청 성공');
        setText(response.data.text);
      })
      .catch(error => {
        // 에러 핸들링
        alert('요청 실패');
        console.log(error);
      });
  }, []);
  • 클라이언트
    • 서버로 보낼 key-value를 가진 객체를 생성.
    • post요청 2번째 인수로 해당 객체를 넣는다.

// server > index.js

// 클라이언트에서 보낸 데이터를 파싱하기 위해 사용하는 2가지 코드
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// 클라이언트에서 보낸 데이터에 접근하기
app.post('/api/test', (req, res) => {
  console.log(req.body.author);
  res.status(200).json({ success: true, text: 'hi' });
});
  • 서버
    • 클라이언트에서 보낸 요청을 바디파서로 파싱해서 받아와야 함. (설치 필요 x)
    • req.body.key값 으로 접근

Mongoose Model

참고 https://mongoosejs.com/docs/index.html

  • Model : 스키마를 감싸주어 해당 스키마를 쓸 수 있게 해주는게 Model.
  • Schema : 저장될 데이터의 형태를 정의한다.
  • Collection : 같은 성격의 데이터들이 묶인 모둠을 말한다.

MongoDB는 NoSQL이므로 SQL보다는 더 자유롭게 데이터를 저장할 수 있지만 그렇다고 아무런 규칙이 없는 것은 아니다.

MongoDB에서는 같은 성격의 데이터를 Collection 으로 묶어주어야 한다. 예를 들어 유저 정보는 user 콜렉션에, 글 정보는 post 콜렉션에 담아두는 등의 방식으로 묶는다.

server 폴더에 Model 들을 관리할 Model 폴더를 만들고 Collection 별로 묶을 모델과 스키마를 정의한 파일을 만들고 모듈로 export.

express 서버를 만든 index.js에서 이 모듈을 import 해온다.

// server > Model > Post.js

const mongoose = require('mongoose');

// 1. 스키마의 내부에 저장될 데이터의 형태를 정의. (생성자 함수)
const postSchema = new mongoose.Schema({
  title: String,
  content: String,
});

// 2. 모델을 선언.
const Post = mongoose.model('Post', postSchema);

// 3. 모듈 export.
module.exports = { Post };

DB에 데이터 넣기 - 모델 import & 인스턴스 생성

// 4. 정의한 모델을 import 해오기
// server > index.js

// ... 생략

const { post } = require('./Model/Post');

// ... 생략

// 5. post 요청 시 인스턴스 생성.
app.post('/api/test', (req, res) => {
  const communityPost = new Post({
    title: '글제목이다',
    content: '글내용이다',
  },
	{ collection: 'posts' } // 콜렉션 지정
);
	communityPost.save(); // .save() 없으면 db로 데이터 안넘어옴!!
  res.status(200).json({ success: true, text: 'hi' });
});

이제 post 요청이 오면 db로 스키마에서 정의한 데이터 형식으로 지정한 콜렉션에 데이터가 들어온다.

db 이름 바꾸는 법 : mongoURI에서 mongodb.net/ 뒤에서 ?retryWrites=true 사이에 db 이름을 넣는다. 미기재시 test 란 이름으로 db 생성됨.

줌 세션

웹 표준만 잘 지켜도 크로스 브라우징이나 seo, 웹 접근성은 어느정도 갖춰지기 때문에 웹 표준을 지켜서 개발해야 한다.

WAI-ARIA는 어디까지나 보조적인 역할이다. 꼭 필요한 경우에만 사용한다. 시멘택한 태그 사용으로 해결할 수 있는 경우엔 태그 사용만으로 해결하고 그 외에 보조적인 설명이 필요할 때 사용한다.

material-ui, chakra-ui 등 ui 라이브러리의 예시에서 WAI-ARIA 사용 방법을 참고하면 좋다.

background가 이미지인 button 요소의 경우 스크린리더에서 이미지의 의미 전달을 위해 WAI-ARIA의 aria-label 속성을 써줄 수 있다.

더 공부할 내용

  • useEffect 안의 코드가 2번 실행되는 경우에 index.js에서 React.StrictMode 컴포넌트를 지우면 해결되는 이유?
  • useEffect의 dependency array 문제. 단순히 린터를 끄면 될 문제인지? https://bobbyhadz.com/blog/react-hook-useeffect-has-missing-dependency

3. 리뷰

마냥 왕초보 던전에서 머물것만 같았는데 어느덧 부트캠프가 점점 끝이 다가오는게 느껴진다. 섹션2를 마치면서는 불안감에 압도당해서 어찌할 줄 몰라했는데 팀프로젝트가 다가온다는 압박감은 오히려 줄어든 것 같다.

서버 코드는 아무리 봐도 적응이 안된다. 계속 보면 나아지겠지만 지금은 어렵다.

728x90
저작자표시 비영리 변경금지

'기록 > 코드스테이츠 프론트엔드' 카테고리의 다른 글

12주 4일차 - Auth Basic  (0) 2022.07.15
12주 3일차 - 네트워크, CRUD, Authentication  (0) 2022.07.13
12주 1일차 - 데일리코딩 뜯어보기  (0) 2022.07.11
11주차 마무리 - 힐링  (0) 2022.07.10
11주차 토요일  (0) 2022.07.09
    '기록/코드스테이츠 프론트엔드' 카테고리의 다른 글
    • 12주 4일차 - Auth Basic
    • 12주 3일차 - 네트워크, CRUD, Authentication
    • 12주 1일차 - 데일리코딩 뜯어보기
    • 11주차 마무리 - 힐링
    FE RYAN
    FE RYAN

    티스토리툴바