ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React] 개발자 지망생 스터디 - 26일차
    스터디/KAKAOCLOUDSCHOOL 2022. 12. 7. 17:50

    10. useCallback

    1) 개요

    > 특정 함수를 새로 만들지 않고 재사용하고자 할 때 사용
    > 컴포넌트에 구현한 함수들은 컴포넌트가 랜더링될 때 마다 다시 생성
    > 컴포넌트가 많아지고 랜더링이 자주 발생하면 함수들을 다시 만드는 것은 비효율적이 될 수 있음
    > useCallback을 이용하면 데이터가 변경된 경우에만 함수를 다시 만들도록 할 수 있음
    > 첫번째 매개변수는 함수이고 두번째 매개변수는 데이터의 배열임

    2) Average.jsx 파일을 수정

    🗂 react_hooks → 📁 src → 📄 Average.jsx

    import React, {useState, useMemo, useCallback} from 'react';
    
    //배열의 평균을 구해서 리턴해주는 함수
    const getAverage = (numbers) => {
        console.log("평균 계산");
        if(numbers.length === 0)
            return 0;
        //reduce는 배열을 순회하면서 연산을 수행한 후 하나의 값을 리턴
        //매개변수는 2개인데 첫번째 매개변수는 수행할 함수이고
        //두번째 매개변수는 연산을 시작할 때의 초기값입니다.
        //두번째 매개변수를 생략하면 배열의 첫번째 요소로 설정
        //첫번째 매개변수인 함수는 매개변수를 4개까지 갖는데
        //첫번째는 누적값이고 두번째는 배열의 요소
        //세번째는 배열의 인덱스이고 네번째는 배열
    
        //[10, 20, 130, 240]
        //10+20=30, 30+130=160, 160+240=400 400리턴
        const sum = numbers.reduce((a, b) => a + b);
        return sum / numbers.length;
    }
    
    
    const Average = () => {
        
        //숫자 배열
        const [list, setList] = useState([]);
        //useMemo를 이용해서 getAverage를 호출
        //list에 변화가 생긴 경우만 메서드를 호출하고
        //그 이외의 경우는 결과를 재사용합니다.
        const avg = useMemo(() => getAverage(list), [list])
    
        //입력받은 내용
        const [number, setNumber] = useState('');
        //input에 내용을 수정할 때 호출될 메서드
        const onChange = useCallback(e => {setNumber(e.target.value)},
        []);
        //추가를 눌렀을 때 호출될 메서드
        //이 함수는 number 와 list가 변경될 때 만 다시 생성
        const onInsert = useCallback(e => {
            const nextList = list.concat(parseInt(number));
            setList(nextList);
            setNumber('');
        }, [number, list]);
    
        return(
            <div>
                <input value={number} onChange={onChange}/>
                <button onClick={onInsert}>추가</button>
                <ul>
                    {list.map((value, index) => (
                        <li key={index}>{value}</li>
                    ))}
                </ul>
                <div>
                    <b>평균:</b>{avg}
                </div>
            </div>
        )
    }
    
    export default Average;

    11. React.memo

    1) 개요

    > 컴포넌트의 props 가 변경되지 않았다면, 리랜더링을 방지해서 리랜더링의 성능 최적화를 해줄 수 있는 함수
    > 이 함수를 이용해서 컴포넌트를 감싸주기만 하면 리랜더링이 필요한 상황에서만 리랜더링을 함

    2) Average.jsx 수정

    🗂 react_hooks → 📁 src → 📄 Average.jsx

    import React, {useState, useMemo, useCallback} from 'react';
    
    //배열의 평균을 구해서 리턴해주는 함수
    const getAverage = (numbers) => {
        console.log("평균 계산");
        if(numbers.length === 0)
            return 0;
        //reduce는 배열을 순회하면서 연산을 수행한 후 하나의 값을 리턴
        //매개변수는 2개인데 첫번째 매개변수는 수행할 함수이고
        //두번째 매개변수는 연산을 시작할 때의 초기값입니다.
        //두번째 매개변수를 생략하면 배열의 첫번째 요소로 설정
        //첫번째 매개변수인 함수는 매개변수를 4개까지 갖는데
        //첫번째는 누적값이고 두번째는 배열의 요소
        //세번째는 배열의 인덱스이고 네번째는 배열
    
        //[10, 20, 130, 240]
        //10+20=30, 30+130=160, 160+240=400 400리턴
        const sum = numbers.reduce((a, b) => a + b);
        return sum / numbers.length;
    }
    
    
    const Average = () => {
        
        //숫자 배열
        const [list, setList] = useState([]);
        //useMemo를 이용해서 getAverage를 호출
        //list에 변화가 생긴 경우만 메서드를 호출하고
        //그 이외의 경우는 결과를 재사용합니다.
        const avg = useMemo(() => getAverage(list), [list])
    
        //입력받은 내용
        const [number, setNumber] = useState('');
        //input에 내용을 수정할 때 호출될 메서드
        const onChange = useCallback(e => {setNumber(e.target.value)},
        []);
        //추가를 눌렀을 때 호출될 메서드
        //이 함수는 number 와 list가 변경될 때 만 다시 생성
        const onInsert = useCallback(e => {
            const nextList = list.concat(parseInt(number));
            setList(nextList);
            setNumber('');
        }, [number, list]);
    
        return(
            <div>
                <input value={number} onChange={onChange}/>
                <button onClick={onInsert}>추가</button>
                <ul>
                    {list.map((value, index) => (
                        <li key={index}>{value}</li>
                    ))}
                </ul>
                <div>
                    <b>평균:</b>{avg}
                </div>
            </div>
        )
    }
    
    export default React.memo(Average);

     


    react styling

    • 스타일 적용

    1. styling 방식

    • 일반 CSS 사용
    • Sass : CSS 전처리기(pre-processor) 를 이용하는 방식으로 확장된 CSS 문법 사용
    • CSS Module : 스타일을 작성할 때 CSS 클래스 이름이 다른 CSS 클래스 이름과 충돌하지 않도록 파일마다 고유한 이름을 자동으로 생성해주는 옵션
    • styled-components : 컴포넌트 안에 스타일을 내장시키는 방식으로 동일한 스타일이 적용된 컴포넌트를 사용하는 방식
      - 💡 실제 애플리케이션 제작 작업을 할 때 이런 방식으로 만들어진 컴포넌트들을 많이 이용

    2. 일반 CSS 적용

    1) 개요

    > webpack 의 css-loader 를 이용해서 일반 CSS 를 불러오는 방식
    > react 프로젝트를 생성하면 App.js 가 App.css를 불러와서 적용

    2) Naming

    > react 프로젝트에서는 컴포넌트-클래스 이름의 형태로 네이밍
       App-header : App 컴포넌트 안에 header라는 클래스를 의미함
    > BEM(Block Element Modifier) 방법 - CSS 에서는 가장 많이 사용
       각각의 요소는 - 나 _ 로 구분함
       블럭요소이름__요소이름__수정자이름 의 형태로 네이밍
    > SMACSS(Scalable and Modular Architecture for CSS) - 확장형 모듈식 구조
       Base에는 아무런 접두어도 붙이지 않고 Layout 관련된 경우는 I - 이름을 정하는 방식
       State의 경우는 is- 또는 s- 등을 추가
       용도를 파악하기 편리
    > 이외에도 OOCSS 등이 있음

    3) App.css를 수정해서 적용

    🗂react_styling → 📁 src → 📄 App.js
    > App.css 파일에 추가 (App 클래스 안에 a 태그)
    .App a{
      color: #333333;
    }

     

    3. CSS Module 사용

    1) 개요

    > CSS를 불러와서 사용할 때 클래스 이름을 고유한값으로 만들어서 적용
       [파일이름]_[클래스이름]_[해시값] 을 추가해서 클래스 이름을 부여
    > 사용하는 방법은 CSS 파일의 확장자를 .module.css 로 만들면 됨
    > 이 기능을 사용할 때는 CSS 파일의 클래스 이름을 일반적인 이름으로 사용하면 됨
    > 별도의 클래스 이름을 부여하지 못하도록 하고자 하는 경우에는 클래스 이름 앞에 : global을 추가하면 됨

    2) 적용

    # CSS 파일을 생성 - 이름.module.css
    🗂react_styling → 📁 src → (CREATE) 📄 CSSModule.module.css
    /* 파일 안에서만 사용하는 클래스 */
    .wrapper{
        background: black;
        padding: 1em;
        color: white;
        font-size: 2rem;
    }
    
    /* 모든 곳에서 사용할 수 있는 클래스 - 이름을 수정하지 않음 */
    :global .something{
        font-weight: 800;
        color: aqua;
    }

    # css 파일의 디자인을 적용할 컴포넌트 생성
    🗂react_styling → 📁 src → (CREATE) 📄 CSSModule.jsx
    import React from "react";
    import styles from "./CSSModule.module.css";
    
    const CSSModule = () => {
        return(
            <div className = {styles.wrapper}>
                처음 사용해보는
                <span className="something">CSS Module</span>
            </div>
        )
    
    }
    export default CSSModule;

    3) 여러 개의 클래스 동시 적용

    # CSSModule.module.css 파일에 클래스 추가
    📁 src → 📄 CSSModule.module.css
    .inverted{
        color:black;
        background: white;
        border: 1px solid black;
    }​

    # CSSModule.jsx 파일 수정
    📁 src → 📄 CSSModule.jsx

    import React from "react";
    import styles from "./CSSModule.module.css";
    
    const CSSModule = () => {
        return(
            <div className = {`${styles.wrapper} ${styles.inverted}`}>
                처음 사용해보는
                <span className="something">CSS Module</span>
            </div>
        )
    
    }
    export default CSSModule;

    4. classnames 라이브러리

    1) 개요

    > CSS 클래스를 조건부로 설정할 때 유용한 라이브러리로 여러 클래스를 설정할 때 편리

    # 설치

    ☑︎ yarn : yarn add classnames
    ☑︎ npm : npm install classnames

    # 설정 예시

    ☑︎ 2개 설정 : classNames('one', 'two')
    ☑︎ 3개 설정 : classNames('one', ['two', 'three'])
    ☑︎ 조건부 설정
    > two 적용 : classNames('one', {'two':ture})
    > two 적용 불가 : classNames('one', {'two':false})
    :: true 나 false 위치를 변수로 설정하면 조건부 설정을 쉽게 구현하는 것이 가능함

    2) CSSModule.jsx 에 적용

    # 설치
    $yarn add classnames

    #CSSModule.jsx 수정
    📁 src → 📄 CSSModule.jsx
    import React from "react";
    import styles from "./CSSModule.module.css";
    import classNames from 'classnames/bind';
    
    // cx 안에서는 styles 생략하는 것이 가능
    const cx = classNames.bind(styles);
    
    const CSSModule = () => {
        return(
            <div className = {cx('wrapper', 'inverted')}>
                처음 사용해보는
                <span className="something">CSS Module</span>
            </div>
        )
    
    }
    export default CSSModule;​

     

    5. SASS

    1) CSS Preprocessor(전처리기)

    > CSS 가 동작하기 전에 사용하는 기능
    > CSS의 불편함을 해결하기 위한 확장 기능
    > 문법 자체는 CSS와 유사하지만 선택자의 중첩이나 조건문, 반복문, 다양한 단위의 연산 등이 가능함
    > Sass, Less, Stylus 등이 있음

    2) SASS

    > Syntactically Awesome Style Sheets
    > 중복되는 코드를 줄여 가독성 좋게 작성이 가능함
    > 가이드 참고 : https://sass-guidelin.es/ko/
    # SCSS
    > CSS 구문과 호환되도록 새로운 구문을 도입해 만든 SASS의 기능을 지원하는 CSS 의 super set
    > 사용하기 위해서는 패키지 설치 필요
       $yarn add node-scss scss-loader sass  
    > 확장자는 scss를 사용
     

    Sass Guidelines — Korean translation

    분별 있고, 유지∙확장 가능한 Sass 작성을 위한 주관적인 스타일가이드.

    sass-guidelin.es

    3) CSSModule.module.css 파일을 수정해서 적용

    📁 src → 📄 CSSModule.module.css
    /* 파일 안에서만 사용하는 클래스 */
    .wrapper{
        background: black;
        padding: 1em;
        color: white;
        font-size: 2rem;
    
        /* wrapper 와 inverted가 모두 있는 경우에만 적용 */
        & .inverted{
            color:black;
            background: white;
            border: 1px solid black;
        }
    }
    
    /* 모든 곳에서 사용할 수 있는 클래스 - 이름을 수정하지 않음 */
    :global {
        .something {
            font-weight: 800;
            color: goldenrod;
        }
    }

    # CSSModule.jsx 파일 수정
    📁 src → 📄 CSSModule.jsx

    import styles from "./CSSModule.module.scss";​

    4) scss 파일을 생성하고 적용

    # App.scss 파일을 생성하고 작성
    📁 src → (CREATE) 📄 App.scss
    import CSSModule from './CSSModule';
    
    import styles from './App.scss';
    import classNames from 'classnames/bind';
    
    const cx = classNames.bind(styles);
    
    function App() {
      const isBlue = false;
      return(
        <div>
          <div className={cx('box',{blue:isBlue})}>
            <div className={cx('box-inside')}/>
          </div>
          <CSSModule/>
        </div>
      )
    }
    export default App;​

    5) 변수와 믹스 인 사용

    > $변수명:값; 의 형태로 변수를 만들어서 다른 곳에서 @import를 이용해서 사용이 가능
    > 믹스 인은 여러 속성을 모아놓은 것
    @mixin 이름(){
    	속성:값
        ...
    }
    
    @incluse 이름();​
    > 변수와 믹스 인은 자주 사용하는 속성이 있을 때 유용함

    # src 디렉토리에 styles 디렉토리 생성
    📁 src → (CREATE) 📁 stytles

    # 공통된 스타일 속성을 정의한 util.scss 파일 생성
    📁 src → 📁 styles → (CREATE) 📄 util.scss
    $size:100px;
    
    @mixin place-at-center(){
        top:50%;
        left:50%;
        transform:translate(-50%, -50%);
    }

    # App.scss 파일 상단에 코드를 추가하고 설정을 수정
    📁 src → 📄 App.scss
    :: @import './styles/util.scss';
    :: width : $size
    :: height : $size
    :: @include place-at-center();
    @import './styles/util.scss';
    
    .box{
        display: inline-block;
        width: $size;
        height: $size;
        border: 1px solid black;
        position: fixed;
    
        @include place-at-center();
    
        &.blue{
            background: blue;
        }
    
        &:hover{
            background: yellow;
        }
    
        &:active{
            background: red;
        }
    
        .box-inside{
            background: black;
            width: 50px;
            height: 50px;
        }
    }

    > 애플리케이션을 개발하다 보면 컴포넌트 1개와 scss 파일 1개가 쌍으로 만들어지는 경우가 많음
    > 여러 컴포넌트를 만들다 보면 공통적으로 사용하는 scss 라이브러리들이 있는데 이러한 라이브러리들을 util.scss 에서 import하면 다른 곳에서도 별도의 import 없이 사용하는 것이 가능함

    6) SCSS 라이브러리

    > SCSS가 이미 적용된 라이브러리
    > 반응형 웹 디자인(디바이스의 크기에 상관없이 동일한 콘텐츠를 사용할 수 있도록 하는 것) : include- media
    > 색상 : open-color(색상을 자주 사용하는 색상 이름과 숫자를 이용해서 강도를 설정하는 형태)
    > icon : react-icons

    ※ 참고 자료
    include-media : https://www.npmjs.com/package/include-media
    open-color : https://yeun.github.io/open-color/
    react-icon : https://react-icons.github.io/react-icons/
     

    include-media

    Simple, elegant and maintainable media queries in Sass. Latest version: 1.4.10, last published: 2 years ago. Start using include-media in your project by running `npm i include-media`. There are 120 other projects in the npm registry using include-media.

    www.npmjs.com

     

    Open Color

    Color scheme for UI design

    yeun.github.io

     

    React Icons

    React Icons Include popular icons in your React projects easily with react-icons, which utilizes ES6 imports that allows you to include only the icons that your project is using. Installation (for standard modern project) npm install react-icons --save Usa

    react-icons.github.io

    # 라이브러리 설치
    $yarn add include-media open-color react-icons

    #util.scss 파일 수정
    📁 src → 📁 styles → 📄 util.scss
    @import '~open-color/open-color';
    @import '~include-media/dist/include-media';
    
    $breakpoints:(
        small:376px,
        medium:768px,
        large:1024px,
        huge:1200px
    );
    
    $size:100px;
    
    @mixin place-at-center(){
        top:50%;
        left:50%;
        transform:translate(-50%, -50%);
    };​

    # 컴포넌트를 만들 때 디렉토리 구조
    > src 디렉토리 안에 components 라는 디렉토리를 생성
       components 디렉토리 안에서 컴포넌트 파일과 디자인 파일을 생성
       디렉토리 안에 컴포넌트 이름으로 디렉토리를 생성하고 컴포넌트 파일과 디자인 파일 그리고 index.js(컴포넌트를 내보내는 역할
       만 수행) 파일을 생성

    # 컴포넌트를 저장할 components 디렉토리 생성
    📁 src → (CREATE) 📁 components

    # components 디렉토리에 Button.jsx 파일 생성
    📁 src → 📁 components → (CREATE) 📄 Button.jsx
    import React from "react";
    import styles from './Button.scss';
    import classNames from "classnames/bind";
    
    const cx = classNames.bind(styles);
    
    // props를 받아오는데 children으로 넘겨준 것은 children으로 받고 나머지는 rest로 받기
     const Button = ({children, ...rest}) => {
         return(
             <div className={cx('button')}{...rest}>
                 {children}
             </div>
         )
     }
    
     export default Button;


    # components 디렉토리에 Button.scss 파일을 생성하고 작성
    📁 src → 📁 components → 📄 Button.scss
    @import '../styles/util.scss';
    
    .button{
        background: $oc-green-7;
        transition: all .2s ease-in;
        display: inline-block;
        padding-top: 2rem;
        padding-bottom : 2rem;
        text-align: center;
        color: white;
        position: fixed;
        font-size: 2rem;
        border-radius: 4px;
    
        cursor:pointer;
        @include place-at-center();
    
        width: 1200px;
        // 반응형 웹디자인
        @include media("<huge"){
            width:1024px;
        }
        @include media("<large"){
            width:768px;
        }
        @include media("<medium"){
            width:90%;
        }
    
        &:hover{
            background: $oc-green-7;
        }
        &:active{
            margin-top: 3px;
            background: $oc-green-8;
        }
    }

     

    # App.js 파일에 Button component

    7) Material Design

    #개요
    > 웹 과 앱을 통틀어 모든 개발 플랫폼에서 사용자 경험을 하나로 묶기 위해서 (Progressive Web Design) 구글이 제시한 디자인 방식

    #사용방법
    > CDN 방식 - 스타일시트의 외부 링크 이용하는 것으로 네트워크를 사용할 수 없는 상태가 되면 적용되지 않음

    💡 CDN(Content Delivery-Distrubution Network)
    서버와 사용자 사이의 물리적인 거리를 줄여 콘텐츠 로딩에 소요되는 시간을 최소화하기 위해서 동일한 콘텐츠를 여러 네트워크에 분산 저장해서 요청을 하면 가장 가까운 Network에서 다운로드 하도록 해주는 서비스

    > scss 파일이나 css 파일을 다운로드 받아서 적용 - 네트워크 사용 여부와 상관없이 사용할 수 있지만 앱의 크기가 커짐

    # public 디렉토리 index.html 파일에 내용 수정
    📁 public → 📄 index.html

    :: <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"/>
    ...
    <link rel="stylesheet"
    href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"/>
    <title>React App</title>
    ...

    # App.js 파일 내용 작성
    📁 src → 📄 App.js
    import './App.css';
    
    function App() {
      return(
        <div>
          <nav>
            <div className="nav-wrapper">
              <div>REACT</div>
            </div>
          </nav>
          <div>머터리얼 디자인</div>
        </div>
      )
    }
    export default App;​
    > 실행하고 위의 div와 아래의 div를 확인

    # 다운로드 받아서 직접넣고 사용
    > https://materializecss.com 에서 css나 scss를 다운로드
    > 압축파일을 해제하고 프로젝트에 복사 (sass 폴더를 src 하위로 옮김)
    🗂Project → 📁 src → (COPY) 📁 sass
    > sass 디렉토리의 materialize.scss를 import 해서 사용
     

    Documentation - Materialize

     

    materializecss.com

    6. styled-components

    1) 개요

    > 자바스크립트 파일 안에 스타일을 선언하는 방식 - CSS in JS
    > 컴포넌트와 디자인을 분리하지 않고 컴포넌트 와 디자인을 하나의 파일로 만들어서 사용하는 것으로 컴포넌트를 배치하면
       자동으로 디자인이 적용
       react-icons 의 각 icon을 컴포넌트를 삽입하는 형태로 추가하면 이미 설정된 style이 적용되서 출력이 됨
    > 이러한 라이브러리의 종류는 https://github.com/MicheleBertoli/css-in-js 에서 확인 가능
     

    GitHub - MicheleBertoli/css-in-js: React: CSS in JS techniques comparison

    React: CSS in JS techniques comparison. Contribute to MicheleBertoli/css-in-js development by creating an account on GitHub.

    github.com

    2) styled-component 를 이용한 버튼 만들기

    # 패키지 설치
    $yarn add styled-components

    # components 디렉토리에 StyledComponent.jsx 파일로 만들고 작성
    🗂react_styling →  📁 components → (CREATE) 📁 StyledComponent.jsx
    import React from "react";
    import styled, {css} from 'styled-components';
    
    const Box = styled.div`
        backgroud:${props => props.collor || 'blue'};
        padding:1rem;
        display:flex;
    `;
    
    const Button = styled.button`
        background:white;
        color:black;
        border-radius:4px;
        padding:0.5rem;
        display:flex;
        align-items:center;
        justify-content:center;
        box-sizing:border-box;
        font-size:1rem;
        font-weight:600;
    
        &:hover {
            background: rgba(255, 255, 255, 0.9);
        }
    
        & + button {
            margin-left: 1rem;
        }
    `;
    
    const styledComponent = () => {
        <Box color='black'>
            <Button>안녕하세요</Button>
            <Button>반갑습니다</Button>
        </Box>
    };
    
    export default styledComponent;​

    #App.js에서 파일 출력

    import StyledComponent from './components/StyledComponent';
    import './App.css';
    
    function App() {
      return(
        <div>
          <StyledComponent/>
        </div>
      )
    }
    export default App;

    7. 서버에서 데이터 받아오기

    https://jsonplaceholder.typicode.com/users

    1) 서버에서 데이터 받아오는 방법

    #1 : ajax 이용 - load 이벤트 와 error 이벤트를 처리
    import React from "react";
    
    function App() {
      return(
        <div>
          <button onClick={(e)=>{
            let request = new XMLHttpRequest();
            // GET 방식으로 요청
            request.open('GET', 'https://jsonplaceholder.typicode.com/users');
            // POST 방식일 때는 send에 파라미터를 대입
            request.send('');
            request.addEventListener('load', ()=>{
              let data= JSON.parse(request.responseText);
              // 데이터를 가져오는데 성공했을 때 처리
              console.log(data);
            });
            request.addEventListener('error', (error)=>{
              // 데이터를 가져오는데 실패했을 때 처리
              console.log(error);
            });
          }}> 다운로드 </button>
        </div>
      )
    }
    export default App;​


    #2 : Fetch API : Promise를 이용하는 API

    import React from "react";
    
    function App() {
      return(
        <div>
          <button onClick={(e)=>{
            fetch('https://jsonplaceholder.typicode.com/users')
            .then((response) => response.json())
            .then((data) => console.log(data))
            .catch((error) => console.log(error.message))
          }}> 다운로드 </button>
        </div>
      )
    }
    export default App;


    #3 : axios 라이브러리를 사용
    > $yarn add axios

    import React from "react";
    import axios from 'axios';
    
    function App() {
      return(
        <div>
          <button onClick={(e)=>{
            axios.get('https://jsonplaceholder.typicode.com/users')
            .then(response => console.log(response.data))
            .catch(error => console.log(error))
          }}> 다운로드 </button>
        </div>
      )
    }
    export default App;​

    > #3의 경우 코드가 상당히 간단해져서 사용하기 편리하나 라이브러리로서 변경될 경우에 대비해야한다.
       따라서, 라이브러리를 사용하지 않는 #2의 Fetch API로 사용하는 것을 권장함

    2) Node 서버에서의 CORS 설정

    # cors 라이브러리 설치
    $yarn add cors
    $npm add cors

    # 서버 실행 파일에 추가 (Node에서만 사용 가능)
    const cors = require('cors');
    app.use(cors());

    3) 서버를 수정할 수 없을 때 proxy 설정

    # package.json 파일에 설정을 추가
    > "proxy" : "서버의 도메인"
    > 요청을 할 때 /api/도메인 뒤의 url 로 요청하면 됨

    # 라이브러리를 이용
    > 라이브러리 설치
    $yarn add http-proxy-middleware

    > src 디렉토리의 setupProxy.js 파일을 만들고 작성
    const {createProxyMiddleware} = require('http-proxy-middleware');
    module.exports = (app) => {
    	app.use(createProxyMiddleware('/클라이언트공통URL',{
        	target:'서버의URL',
            changeOrigin:true
        	})
    	);
    }

    > http://localhost:9000/item/itemid에 요청

    const {createProxyMiddleware} = require('http-proxy-middleware');
    module.exports = (app) => {
    	app.use(createProxyMiddleware('/api',{
        	target:'http://localhost:9000',
            changeOrigin:true
            })
    	);
    }
Designed by Tistory.