React - 02

월요일좋아·2022년 12월 29일
0

React

목록 보기
2/11

※ 깃허브 레포지토리명과 프로젝트명은 같아야 함
다를 경우 : 터미널에서 npm install 입력, node modules 라는 폴더가 생김
그 후 프로젝트 종료
탐색기로 가서 해당 프로젝트의폴더 내의 .idea 폴더 -> 프로젝트명.iml 파일 복사 -> 프로젝트 폴더 바깥에 붙여넣은 후 레포지토리명과 동일하게 iml파일 이름을 바꾼 후 내용 편집 -> 해당 iml 파일 내부의 프로젝트명을 모두 레포지토리명과 동일하게 바꿔줌
.iead폴더 내부의 vcs.xml, workspace.xml 등의 모든 파일의 내용도 동일하게 확인해서 프로젝트명으로 되어있는 부분을 레포지토리명으로 바꿔줌
구성편집 -> 스크립트:start

ES6 문법

확장 표현식

ES6 버전에서 추가된 object 타입의 사용 방식

ES5 버전

  • Destructuring.js
// Destructuring.js

console.log('----- ES5 -----');
var x = 0;
var y = 0;
var obj = {x: x, y: y};
console.log(obj);

var randomKeyString = 'other';
var combined = {};

combined['one' + randomKeyString] = 'some value';
console.log(combined);

ES6 버전

  • Destructuring.js
console.log('\n----- ES6 -----');
var x = x;
var y = y;
// object 생성 시 키값을 설정하지 않으면 변수명이 키값으로 설정됨
var obj = {x, y}; // ES5) x --> 키이름, 변수명
console.log(obj);

// object 타입 생성 시 대입 연산자 오른쪽에서 바로 키와 값을 설정하여 object 타입에 데이터를 추가하는 것이 가능
var randomKeyString = 'other';
var combined = {['one' + randomKeyString]: 'some value'};
console.log(combined);

ES5 버전

  • Destructuring.js
console.log('\n----- ES5 -----');
var obj2 = {
  methodA: function () { console.log('A');},
  methodB: function () { return 0;}
};
console.log(obj2);
obj2.methodA();
obj2.methodB();

ES6 버전

데이터 집어넣을때 익명함수 안써도 되고 멤버 메서드 쓰듯 바로 쓰면 됨

  • Destructuring.js
console.log('\n----- ES6 -----');

var obj2 = {
  methodA() { console.log('A');},
  methodB() { return 0;}
}

구조분해할당

ES5

  • Destructuring.js
console.log('\n----- 구조분해할당 -----');

console.log('\n----- ES5 -----');
var list = [0, 1];
var item1 = list[0];
var item2 = list[1];
var item3 = list[2] || -1;
console.log(item1); // 0
console.log(item2); // 1
console.log(item3); // -1

// 데이터 스왑시 임시변수(tmp) 필요
var temp = item2;
item2 = item1;
item1 = temp;
console.log(item1); // 1
console.log(item2); // 0

var obj = {
  key1: 'one',
  key2: 'two'
};

var key1 = obj.key1;
var key2 = obj.key2;
var key3 = obj.key3 || 'default key3 value';
var newKey1 = key1;
console.log(key1);  // one
console.log(key2);  // two
console.log(key3);  // default key3 value
console.log(newKey1); // one

ES6

  • Destructuring.js
var list = [0, 1];
// 대입 연산자 왼쪽에 [] 를 사용하여 그 안에 배열을 쓰듯이 변수명을 입력하면
// 대입연산자 오른쪽의 데이터를 하나씩 꺼내어 내입 연산자 왼쪽의 변수명에 각각 저장됨
var [item1, item2, item3 = 1] = list; // = var [item1, item2, item3 = 1] = [0, 1]
console.log(item1); // 0
console.log(item2); // 1
console.log(item3); // 1

// 확장 표현식을 사용하여 임시 변수 없이 2개의 변ㅅ누의 값을 서로 변경함
[item2, item1] = [item1, item2];
console.log(item1); // 1
console.log(item2); // 0

// 배열의 확장 표현식과 동일하게 object 타입에서도 사용이 가능함
// 대입 연산자 왼쪽에 {} 을 사용하고 변수명을 입력하면, 대입 연산자 오른쪽의 object 타입의 키와 같은 변수명에 데이터를 저장함
// 키 이름 생략 시, 변수명을 키 이름으로 사용하는 법칙 때문임
// : <- 기호를 사용 시 새로운 변수명으로 적용
// = <- 기호를 사용 시 기본값으로 설정
var {key1: newKey1, key2, key3 = 'default key3 value'} = obj; // obj = { key1: 'one', key2: 'two'}
console.log(newKey1); // one
console.log(key2);  // two
console.log(key3);  // default key3 value

var [item, ...otherItems] = [0, 1, 2];
console.log(item);  // 0
console.log(otherItems);  // [1, 2]

var {key1, ...others} = {key1: 'one', key2: 'two'};
console.log(key1);  // one
console.log(others);  // {key2: 'two'}

클래스

자바의 클래스보다는 간소화 된 방식이지만 ES6 부터는 자바스크립트에서도 Class 키워드를 지원함
constructor(매개변수) : 자바스크립트 클래스의 생성자, 자바스크립트의 생성자는 이름을 지정할 수 없음
extends: 자바스크립트의 클래스도 상속을 지원함

  • Class.js
// Class.js

// 클래스 선언
class Shape {

  // 정적 멤버, 클래스명.정적멤버명 으로 사용
  static create(x, y) {
    return new Shape(x, y);
  }

  // 멤버변수 선언 - let, const 등 안붙여도 되는 이유 : 여기서 name 은 '키' 이다!
  name = 'Shape';

  // 생성자, 이름은 constructor 로 고정임
  // 생성자에서 this.변수명 을 입력 시, 멤버 변수가 선언됨
  constructor(x, y) { // 데이터타입은 안써도 자동으로 인식함(자바스크립트의 장점)
    this.move(x, y);  // this : 객체 자기 자신을 의미함
  }

  move(x, y) {  // 키 이름 안써도 됨 사실은 move(x: x, y: y)
    this.x = x;
    this.y = y;
  }

  area() {
    return 0;
  }
}

var s = new Shape(10, 20);
s.area();
s.move(100, 200);
console.log(s.name);
console.log(s.x);
console.log(s.y);

var s1 = Shape.create(0, 0);
s1.area();
s1.move(10, 20);
console.log(s1.name);
console.log(s1.x);
console.log(s1.y);

// 상속(extends)
class Circle extends Shape {

  constructor(x, y, radius) {
    // 부모
    super(x, y);
    // 멤버변수 생성
    this.radius = radius;
  }

  area() {
    if (this.radius === 0) {
      return super.area();
    }
    return this.radius * this.radius;  // 10 * 10
  }
}

var c = new Circle(0, 0, 10);
console.log(c.area());  // 100

배열 함수

  • ES6에서 배열 관련 함수가 추가됨(forEach(), map())

  • forEach()map() 은 반환값이 있냐 없냐의 차이만 있다.

  • forEach() : 지정한 배열의 요소에 callBack으로 지정한 함수의 내용을 실햄하는 함수, 반환값이 없음

    • 사용법 :
      배열명.forEach(콜백함수(현재값이 저장될 변수, 현재 index, 현재 배열 내용) {
      	실행할 소스코드
       })
  • map() : forEach 와 같이 지정한 배열의 요소에 callBack으로 지정한 함수의 내용을 실행하고 그 결과값을 배열로 반환하는 함수

    • 사용법 :
      배열명.map(콜백함수(현재값이 저장될 변수, 현재 index, 현재 배열 내용) {
      	실행할 소스코드
      	return 반환값
       })

forEach( )

  • ArrayMethod.js
const fruits = ['사과', '배', '복숭아'];
console.log('원본 배열 : ' + fruits); // 사과,배,복숭아

// 기존 방식
console.log('\n----- for문 사용 시 -----');
for (let i = 0; i < fruits.length; i++) {
  console.log(fruits[i]);
  // 사과
  // 배
  // 복숭아
}

console.log('\n----- for ~ in 문 사용 시 -----');
for (const item in fruits) {
  // 값이 아니라 key 를 넣기때문에 item을 넣어줘야함
  console.log(fruits[item])
  // 사과
  // 배
  // 복숭아
}


// forEach() 사용 방식
console.log('\n----- forEach 문 사용 시 -----');
fruits.forEach(function (item) {
  console.log(item);
  // 사과
  // 배
  // 복숭아
})


console.log('\n----- forEach 문 매개변수 여러개 -----');
fruits.forEach(function (item, index){
  console.log(`index : ${index}, value: ${item}`);
  // index : 0, value: 사과
  // index : 1, value: 배
  // index : 2, value: 복숭아
})


// 현재 배열 내용 값 넣기 예시
fruits.forEach(function (item, index, arrName) {
  console.log(`current array : ${arrName}, index : ${index}, value : ${item}`);
  // current array : 사과,배,복숭아, index : 0, value : 사과
  // current array : 사과,배,복숭아, index : 1, value : 배
  // current array : 사과,배,복숭아, index : 2, value : 복숭아
});

map( )

console.log('\n----- map 사용 -----\n');
const numbers = [4, 9, 16, 25];
console.log(`원본 배열 : `);
console.log(numbers); // [ 4, 9, 16, 25 ]

let data = numbers.map(function (item) {
  console.log(`현재 값 : ${item}`);  // 4 9 16 25
  return item * 2;
});

console.log(`map 사용 후 데이터 :`);
console.log(data);  //[ 8, 18, 32, 50 ]


console.log('\n----- map() 에서 매개변수 여러개 -----\n');

data = numbers.map(function (item, index) {
  console.log(`index : ${index}, value : ${item}`);
  // index : 0, value : 4
  // index : 1, value : 9
  // index : 2, value : 16
  // index : 3, value : 25

  return item * 2;
});
console.log('map 사용 후 데이터 : ');
console.log(data);  // [ 8, 18, 32, 50 ]

data = numbers.map(function (item, index, current) {
  console.log(`current array : ${current}, index : ${index}, value : ${item}`);
  // current array : 4,9,16,25, index : 0, value : 4
  // current array : 4,9,16,25, index : 1, value : 9
  // current array : 4,9,16,25, index : 2, value : 16
  // current array : 4,9,16,25, index : 3, value : 25

  return item * 2;
});
console.log('map 사용 후 데이터 : ');
console.log(data);  // [ 8, 18, 32, 50 ]

화살표 함수

  • 화살표 함수 : ES6 버전부터 사용되는 함수를 선언하는 새로운 방식
    ES5 버전의 익명함수를 사용하여 함수를 생성하는 방식에서 변경되어 function 키워드를 생략하고, 매개변수와 코드블럭 사이에 => 기호를 사용하는 방식
    소스코드가 반환값 한 줄 일 경우 코드블럭을 생략할 수 있음
    매개변수가 1개 인 경우, 매개변수의 괄호를 생략할 수 있음

  • 사용법 1 :

    변수명 = (매개변수1, 매개변수2, ...) => {
      실행할 소스코드
      return 반환값
    }
  • 사용법 2 : 리턴 키워드, 중괄호 생략

    변수명 = (매개변수1, 매개변수2, ...) => 반환값;
  • 사용법 3 : 매개변수가 1개일때 소괄호까지 생략

    변수명 = 매개변수 => 반환값;
  • 사용법 4 : 매개변수가 없을때 () 로 대체함

    변수명 = () => 반환값;
  • ArrowFunction.js

// 기존 함수 선언 방식 1
function es5Func1(a, b) {
  console.log(a + b);
  return a + b;
}

// 기존 함수 선언 방식 2
var es5Func2 = function (a, b) {
  console.log(a + b);
  return a + b;
}

es5Func1(10, 20); // 30
es5Func2(100, 200); // 300
let data = es5Func1(10, 20) // 30
console.log(data);  // 30
data = es5Func2(100, 200); // 300
console.log(data);  // 300


console.log('\n----- es6 방식 -----')
// 화살표 함수 선언
const es6Func1 = (a, b) => {
  console.log(a + b);
  return a + b;
}

data = es6Func1(10, 20);  // 30
console.log(`리턴 받은 값 : ${data}`);  // 30


// 생략 방법 1
// 생략 전
const es6Func22 = (a, b) => {
  return a + b
}
// --> 생략 후
const es6Func2 = (a, b) =>  a + b;
data = es6Func2(100, 200);
console.log(`리턴 받은 값 : ${data}`); // 300


const es6Func3 = (a, b) => console.log(a + b);
es6Func3(10, 20);


// 매개변수가 1개일때 : 소괄호도 생략가능
const es6Func4 = (a) => a * 2;
data = es6Func4(10);
console.log(`리턴 받은 값 : ${data}`);

const es6Func5 = a => a * 2;
data = es6Func5(10);
console.log(`리턴 받은 값 : ${data}`);


// 매개변수가 없을때 : = => 와 같이 아예 생략은 안되고 = () => 와 같이 사용
const es6Func6 = () => console.log('esFunc5() 실행');
es6Func6();

모듈(export, import)

  • 하나의 자바스크립트 파일에서 다른 자바스크립트의 내용을 사용하기 위한 방식.
    자바스크립트는 원래 html 을 지원하기 위해서 개발된 언어였기 때문에 html 문서 내에서 <script></script> 또는 <script src='파일경로'> </script> 형태로 다른 자바스크립트의 내용을 사용했음.

  • 자바스크립트가 발전하면서 자바스크립트를 단순히 웹에서만 사용하는 것이 아니게 되어,
    외부 자바스크립트 내용을 사용하기 위한 방법이 여러가지로 개발됨.

  • ES6 버전부터 export, import 를 지원함.
    자바스크립트 파일 하나하나를 모듈이라고 함.
    하나의 모듈에는 하나의 export default 가 존재함.

  • html 문서 내에서 import 를 사용하고자 할 경우 <script type="module"> 을 사용하여 해당 파일이 모듈을 사용한다는 것을 알려줘야 함

    <script type="module" src="파일경로><script>
  • node.js 가 ES6 버전이 나오기 이전부터 모듈화 시스템을 사용하고 있었음.
    node.js 가 기본적으로 사용하던 방식이 CommonJS 방식의 모듈 시스템을 사용하고 있었음
    ES6 가 발표되면서 [ import/export ] 를 지원하게 됨.
    기본 방식은 CommonJS 으로 사용되고 ES6 방식으로 사용하려면
    확장자를 .mjs 로 변경하여 사용하던지,
    package.json 파일에 type: "module" 을 추가하여 설정을 해야 함.

  • export : 변수, 함수, 클래스를 다른 자바스크립트 파일에서 사용할 수 있도록 설정
    사용법 :

    export 함수명;  // <-- 함수명이라고 썼지만 변수/함수 모두 사용 가능
     export {함수명1, 함수명2, ...};
     export default 함수명;
  • import : 다른 자바스크립트 파일이 제공하는 변수, 함수, 클래스를 불러와서 사용하도록 설정
    사용법 :
    ↓↓ 일반 export 로 지정된 것을 불러올 때 ↓↓

    import {함수명1, 함수명2, ...} from 파일경로; // <-- 함수명이라고 썼지만 변수/함수 모두 사용 가능

    ↓↓ export default 로 지정된 것을 불러올 때 ↓↓

    import 함수명 from 파일경로;
  • export, import 하는 파일 모두 확장자명을 .js가 아니라 .mjs로 수정해야 한다.

  • 터미널에서 실행할때도 파일명 끝에 .mjs 붙여줘야 정상적으로 실행이 됨

  • 파일생성(설정방법 2가지) : MyMod1.mjs, MyMod2.mjs
    파일생성(사용) : ModuleUse.mjs
    방법1(MyMod1) : 외부로 출력하고자 하는 변수 및 함수, 클래스에 export 를 접두사로 붙임
    방법2(MyMod2) : 변수, 함수, 클래스를 기존에 사용하듯이 다 선언하고, 파일의 끝에서 export 를 진행
    방법2를 보편적으로 사용함

  • MyMod1.mjs

// MyMod1.mjs

// export 로 설정 방법은 두 가지.
// export 로 설정하는 방법 1
// 외부로 출력하고자 하는 변수 및 함수, 클래스에 export 를 접두사로 붙임

export const name = '아이유';
export const gender = '여성';
export const job = '가수';

export const getInfo = () => console.log(`이름 : ${name}, 성별 : ${gender}, 직업 : ${job}`);
  • MyMode2.mjs
// MyMod2.mjs

// export 로 설정하는 방법 2
// 변수, 함수, 클래스를 기존에 사용하듯이 다 선언하고, 파일의 끝에서 export 를 진행

const num1 = 10;
const num2 = 20;

const sum = () => num1 + num2;

const sub = () => num1 - num2;

export {num1, num2, sum};
export default sub;
  • ModuleUse.js
// ModuleUse.mjs

import {name, job, gender, getInfo} from "./MyMod1.mjs";
import {num1, num2, sum} from "./MyMod2.mjs";
import sub from "./MyMod2.mjs";

console.log(name);  // 아이유
console.log(gender);  // 여성
console.log(job); // 가수
getInfo();  // 이름 : 아이유, 성별 : 여성, 직업 : 가수

console.log(`첫번째 숫자 : ${num1} + 두번째 숫자 : ${num2}의 값 : ${sum()}`); 
// 첫번째 숫자 : 10 + 두번째 숫자 : 20의 값 : 30
console.log(`sub() 실행 : ${sub()}`); // -10

Promise (비동기 처리)

  • Promise : 자바스크립트에서 비동기 함수의 동기 처리를 하기 위해서 사용하는 객체
    자바스크립트는 기본적으로 1 쓰레드 비동기 처리 방식을 사용하고 있음 (특정 로직의 실행이 끝날 때까지 기다려주지 않고 나머지 코드를 먼저 실행하는 것이 비동기 처리이다.)
    자바스크립트에서 순차적으로 실행을 하고 싶을 경우 콜백 함수를 이용하여야 함
    순차적으로 실행할 것이 많아지게 되면 콜백지옥이라고 불리는 형태가 만들어지게 됨
    프로미스는 이러한 콜백 지옥을 해결하기 위해서 사용하는 객체임

  • promise 에는 pending, fulfilled, rejected 3가지 상태가 존재함

    • < 상태정보는 실제로 쓰는것은 아니고 상태정보일 뿐임 >
      pending : 대기 상태, 비동기 함수가 실행되고, 아직 처리가 완료되지 않은 상태
      fulfilled : 완료 상태, 비동기 함수가 실행된 후 정상적으로 처리가 완료된 상태
      rejected : 거부 상태, 비동기 함수가 실행된 후 오류가 발생한 상태
  • promise 에는 실행 시 콜백함수가 실행되고, 해당 콜백함수의 매개변수로 resolve(), reject() 이라는 함수를 제공함

    • resolve(매개변수) : 프로미스 실행 후 fulfilled 상태일 경우 실행하는 함수로 나중에 then() 함수를 제공함
    • reject(매개변수) : 프로미스 실행 후 rejected 상태일 경우 실행하는 함수로 나중에 catch() 함수를 제공함
  • 프로미스에는 완료 및 오류처리를 위해서 then(), catch() 함수를 제공하고 있음
    then(매개변수) : 비동기 함수 실행이 완료된 후 실행되는 함수
    catch(매개변수) : 비동기 함수 실행이 거부된 후 실행되는 함수

  • 사용법

    • 선언 :

      function 프로미스를 사용할 함수명(매개변수) {
        return new Promise(function(resolve, reject) {
            비동기 통신 소스...
            비동기 통신 결과에 따라 resolve(), reject();
        });
      }
    • 실행 :

      프로미스를 사용한 함수명()
      .then(function(매개변수) {
       	성공 시 실행할 내용
       })
      .catch(function(매개변수) {
       	실패 시 실행할 내용
       });

자바스크립트의 이벤트 처리 방식 참고 : https://manbalboy.github.io/front/javascript01.html

V8에서 한줄씩 실행을 하다가 이벤트를 만나면 이벤트Queue에 넘기고 V8은 다시 실행해야되는 코드로 돌아가서 그 다음 줄 부터 하나씩 실행함

이벤트 Queue 에서는 먼저 들어온것부터 Event Loop 돌림
워크 쓰레드에서 실행 후 결과를 이벤트 큐로 다시 보냄 -> 이벤트 큐가 다시 실행 -> 끝나면 이벤트 처리가 완전히 끝냈을때 실행하는 부분에 알려줌 (= 콜백)
ajax에서의 success: function() <- function 이 콜백함수임
이것이 비동기 처리임

단점은 콜백지옥이 생김
https://velog.io/@seul06/JavaScript-%EC%BD%9C%EB%B0%B1-%EC%A7%80%EC%98%A5

이것을 해결하고자 만들어진 것이 promise 이다.

  • 프로미스 사용 전 준비
    jquery 추가 : 터미널에 npm install jquery 입력

App.js

import './App.css';
import {getData, getData1} from "./es6/Promise";

function App() {
  getData();

  return (
    <div className="App">

    </div>
  );
}

export default App;
  • Promise.js
// import
import React from "react";
import $ from 'jquery';

// 프로미스 객체를 사용할 함수
function getData() {
  // 콜백함수 resolve, reject
  return new Promise(function (resolve, reject) {
    const data = 100;
    // resolve 를 실행하게되면 .then ~ 부분이 실행이 되고, reject 를 실행하게 되면 .catch ~ 부분이 실행이 됨
    resolve(data);
    // reject(data);
  });
}

getData()
  .then(function (data) {
    console.log(`프로미스 사용 반환값 : ${data}`);
  })
  .catch(function (err) {
    console.log(`프로미스 사용 오류 시 출력 : ${err}`)
  });

const getData1 = function () {
  return new Promise(function (resolve, reject) {
    $.ajax({
      url: 'http://localhost:8080/async/data1',
      type: 'post',
      success: function (data) {
        console.log('통신 성공');
        resolve(data);
      },
      error: function () {
        reject('오류 발생!');
      }
    });
  });
};


// export 선언
export {getData, getData1};
  • App.js에 코드 추가
  getData1()
    .then(function (data) {
      console.log(data);
    })
    .catch(function (err) {
      console.log(err);
    });
  • ajax를 실행하기 위한 서버 생성
  • port 번호가 서로 다를때 생기는 오류

    서버 또는 리액트 에서 옵션을 하나 더 넣어야 함
    @CrossOrigin(origins = "http://localhost:3000") 어노테이션 추가
    @CrossOrigin(origins = "http://localhost:3000")
    @ResponseBody
    @RequestMapping(value = "/async/data1", method = RequestMethod.POST)
    public String asyncData1() {
    	return "서버와 통신 성공";
    }

자바스크립트 비동기 처리와 콜백 함수 쉽게 이해하기
https://joshua1988.github.io/web-development/javascript/javascript-asynchronous-operation/

자바스크립트 Promise 쉽게 이해하기
https://joshua1988.github.io/web-development/javascript/promise-for-beginners/

  • 리액트 개발툴 설치 필수
    크롬 웹스토어 - 확장프로그램 : React Developer Tools 설치

    실행화면

0개의 댓글