TIL 2022-12-29 React 프로미스

JYR00·2022년 12월 29일
0

TIL

목록 보기
51/60

REACT를 깃허브에 올릴 때 레파지토리명과 프로젝트명이 일치하지 않을 경우 프로젝트가 정상적으로 작동하지 않을 수 있다.

프로젝트 파일에 들어가면 소스코드가 존재하기는 한다.
npm install 한 번 해주면 node module을 전부 다운로드 해준다
그러면 node modules가 생성된다
기존의 리엑트 프로젝트 만든 곳에 들어가 imi 파일 하나를 복사해온다.(프로젝트 바깥 폴더에 있어야 함)
이름을 동일하게 변경해준다. 그리고 contenturl 등 여러 군데 프로젝트명을 수정시켜 준다. workspace.xml에서도 열어 보고 수정해야 할 점이 있다면 수정. modules.xml에서도 수정.그냥 다 열어보고 수정해야할 점 있으면 다 수정하삼.
=> 프로젝트로 인식하게 되어서 제대로 동작할 수 있다

구성편집 -> npm + 클릭-> npm 스크립트 생성 run, start 준다
다운받았을 때 npm install해야 모듈 다운로드 받을 수 있다

C:\java505\intellij\react\react_test2\src\es6> node Destructuring.js

es6까지 들어가서 node ...js라고 쳐야 한다.

꿀팁 ! f12누르면 터미널 창으로 간다. f12누르고 화살표 위로 누르면 쉽게 칠 수 있다





확장표현식


// Destructuring.js

// 확장표현식
// ES6 버전에서 추가된 object 타입의 사용방식

console.log('----ES5----');
var x = 0;
var y = 0;
var obj = {x:x, y:y}; //object 타입의 변수 생성 ->{}들어가면 object 타입 // 앞의 건 key, 뒤의 건 value
console.log(obj); //{ x: 0, y: 0 }

var randomKeyString = 'other';
var combined = {}; //빈 object 타입 생성
combined['one' + randomKeyString] = 'some value'; // oneother가 됨 두개 합쳐서 -> value는 some value이다
console.log(combined); //{ oneother: 'some value' }


// 밑에 꺼 하고 난 뒤 추가된 부분
var obj2 = {
    methodA: function () {console.log('A');}, //key에 함수를 넣을 수 있다
    methodB: function () {return 0;} // 값을 주지 않았다
};

console.log(obj2); //{ methodA: [Function: methodA], methodB: [Function: methodB] }
obj2.methodA(); // A
obj2.methodB(); // 출력되는 값이 없다



console.log('----ES6----');
var x = x;
var y = y;
// object 생성 시 키를 설정하지 않으면 변수명이 키값으로 설정됨 {x,y}만 해놓으면 key와 변수명 자동 지정


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

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

var obj2 = {
    methodA() {console.log('A');},
    methodB() {return 0;}
};
console.log(obj2); //{ methodA: [Function: methodA], methodB: [Function: methodB] }
obj2.methodA(); //A
obj2.methodB(); // 결과값없음

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

var list = [0,1];
var item1 = list[0]; //list의 0번째 값
var item2 = list[1]; // list의 1번째 값
var item3 = list[2] || -1;  //기본값 설정 (아이템 값이 없다면 -1을 대입하라)
console.log(item1); // 0
console.log(item2); // 1
console.log(item3); // -1

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('\n----ES6----\n');

var list = [0,1];
// 대입 연산자 왼쪽에 []를 사용하여 그 안에 배열을 쓰듯이 변수명을 입력하면 대입 연산자 오른쪽의 데이터를
// 하나씩 꺼내어 대입 연산자 왼쪽의 변수명에 각각 저장됨
var [item1, item2, item3 = 1] = list; //var [item1, item2, item3 = 1] = [0,1] 3번째 값 없으니까 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 타입의
// 키와 같은 변수명에 데이터를 저장함

// 키의 이름을 생략 시 변수명을 키이름으로 사용한다는 원리를 이용함.
// 콜론 뒤의 변수명들을 새 변수명으로 지정한다. newKey1, key2, key3
// 세미콜론(:) 기호를 사용할 때 새로운 변수명으로 적용
// = 기호 사용시 기본값으로 설정
var {key1 : newKey1, key2, key3 = 'default key3 value'} = 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' } //object 형식으로 받아준다



화살표 함수

// ArrayMethod.js

//ES6에서 배열 관련함수가 추가됨

// forEach() : 지정한 배열의 요소에 callback으로 지정한 함수의 내용을 실행하는 함수. 반환값이 없음
// 사용법 :
// 배열명.forEach(콜백함수(현재값이 저장될 변수, 현재 index, 현재 배열 내용)){
//      실행할 소스코드
// }

// 사용 방법이 좀 다르지만 결과값은 동일하게 출력이 된다
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문 사용시------')
// key를 가져와 넣어줌(value아님)
for(const item in fruits){
    console.log(fruits[item])
}

console.log(' \n--------forEach문 사용시--------')
fruits.forEach(function (item){
    //fruits가 가지고 있는 데이터값을 item에다 넣어서 출력한다
    console.log(item);
    // 사과
    // 배
    // 복숭아
});


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

fruits.forEach(function (item,index,arrName){
    console.log(`current array : ${arrName}, index:${index}, value:{value}`)
//    current array : 사과,배,복숭아, index:0, value:{value}
//    current array : 사과,배,복숭아, index:1, value:{value}
//    current array : 사과,배,복숭아, index:2, value:{value}
});


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

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

let data = numbers.map(function(item){
    console.log(`현재 값 : ${item}`);
    return item * 2;  //바로 return되는 것이 아니고 data에 배열로 쌓인다
//    리턴 값이 나오기 때문에 data처럼 받는 부분이 필요하다
});

console.log(`map 사용 후 데이터 : `);
console.log(data)

// 원본 배열 :
// [ 4, 9, 16, 25 ]
// 현재 값 : 4
// 현재 값 : 9
// 현재 값 : 16
// 현재 값 : 25
// map 사용 후 데이터 :
// [ 8, 18, 32, 50 ]

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

data = numbers.map(function(item,index) {
    console.log(`index : ${index}, value : ${item}`);
    return item * 2;
});

console.log('map 사용 후 데이터 : ');
console.log(data);

data = numbers.map(function (item, index,current){
    console.log(`current array : ${current}, index : ${index}, value:${item}`)
    return item * 2;
});

console.log('map 사용 후 데이터 : ');
console.log(data);



Map, forEach()

// ArrayMethod.js

//ES6에서 배열 관련함수가 추가됨

// forEach() : 지정한 배열의 요소에 callback으로 지정한 함수의 내용을 실행하는 함수. 반환값이 없음
// 사용법 :
// 배열명.forEach(콜백함수(현재값이 저장될 변수, 현재 index, 현재 배열 내용)){
//      실행할 소스코드
// }

// 사용 방법이 좀 다르지만 결과값은 동일하게 출력이 된다
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문 사용시------')
// key를 가져와 넣어줌(value아님)
for(const item in fruits){
    console.log(fruits[item])
}

console.log(' \n--------forEach문 사용시--------')
fruits.forEach(function (item){
    //fruits가 가지고 있는 데이터값을 item에다 넣어서 출력한다
    console.log(item);
    // 사과
    // 배
    // 복숭아
});


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

fruits.forEach(function (item,index,arrName){
    console.log(`current array : ${arrName}, index:${index}, value:{value}`)
//    current array : 사과,배,복숭아, index:0, value:{value}
//    current array : 사과,배,복숭아, index:1, value:{value}
//    current array : 사과,배,복숭아, index:2, value:{value}
});


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

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

let data = numbers.map(function(item){
    console.log(`현재 값 : ${item}`);
    return item * 2;  //바로 return되는 것이 아니고 data에 배열로 쌓인다
//    리턴 값이 나오기 때문에 data처럼 받는 부분이 필요하다
});

console.log(`map 사용 후 데이터 : `);
console.log(data)

// 원본 배열 :
// [ 4, 9, 16, 25 ]
// 현재 값 : 4
// 현재 값 : 9
// 현재 값 : 16
// 현재 값 : 25
// map 사용 후 데이터 :
// [ 8, 18, 32, 50 ]

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

data = numbers.map(function(item,index) {
    console.log(`index : ${index}, value : ${item}`);
    return item * 2;
});

console.log('map 사용 후 데이터 : ');
console.log(data);

data = numbers.map(function (item, index,current){
    console.log(`current array : ${current}, index : ${index}, value:${item}`)
    return item * 2;
});

console.log('map 사용 후 데이터 : ');
console.log(data);



Class 사용하기

// Class.js

// ES6에서부터 자바스크립트에서도 CLASS 키워드를 지원함
// constructor(매개변수) : 자바스크립트 클래스의 생성자, 자바스크립트의 생성자는 이름을 지정할 수 없음
// extends : 자바스크립트의 클래스도 상속을 지원함

class Shape{
    // 정적 멤버, 클래스명.정적멤버명으로 사용
    static create(x,y) {
        return new Shape(x,y);
    }
    //멤버 변수 선언
    //앞에 let,var 같은 것을 집어넣지 않는다.
    //앞에 것은 key이기 때문이다
    // var나 let, const 같은 키워드를 사용하지 않는다
    name = 'Shape';

    //생성자, 이름을 고정
    //생성자에서 this.변수명을 입력 시 멤버 변수가 선언이 된다
    constructor(x,y) {
        this.move(x,y);
    }

    //메서드 선언
    move(x,y){
        this.x =x;
        this.y = y;
    }

    area(){
        return 0;
    }
}

var s = new Shape(0,0);

s.area();
s.move(100,200);
console.log(s.name); //Shape
console.log(s.x); // 100
console.log(s.y); //200


var s1 = Shape.create(0,0);
s1.area();
s1.move(10,20)

console.log(s1.name); //Shape
console.log(s1.x); //10
console.log(s1.y);//20

//extends - 상속(shape를)
class Circle extends Shape {
    constructor(x,y,radius) {
        // this : 나 super :부모
        super(x,y);
        //멤버 변수 생성
        this.radius = radius;
    }

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

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



Export, Import


MyMod1

// MyMod1.js 출력할 모듈
// export로 설정 방법
// 외부로 출력하고자 하는 변수 및 함수, 클래스에 export를 접두사 붙임
// 2번 방법이 더 많이 사용되는 편이다

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

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

MyMod2

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

const num1 = 10;
const num2 = 20;

const sum = () => num1 + num2;
export {num1,num2,sum};

ModuleUse.js

// ModuleUse.mjs

import {name, job, gender, getInfo} from "./MyMod1.mjs";
import {num1, num2, sum} from "./MyMod2.mjs";
// 중괄호 없이 바로 import
import sub from "./MyMod2.mjs";

// node.js가 ES6 버전이 나오기 이전부터 모듈화 시스템을 사용하고 있었음
// node.js가 기본적으로 사용하던 방식이 CommonJS 방식의 모듈 시스템을 사용하고 있었음
// ES6가 발표되면서 import/export를 지원하게 됨
// 기본 방식은 CommonJS으로 사용되고 ES6방식을 사용하려면 확장자가 .mjs를 사용하던지,
// package.json 파일에 type:module를 추가하여 설정을 해야 함. 우리는 전체 파일이 따로 움직이기 때문에 파일명을 바꾸는 걸 추천

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


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

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


js -> mjs로 파일명 변경

package.json에서 module로 설정바꿔도 되지만 우리는 특정 폴더에서만 사용할 것이기 때문에 파일명을 바꾸는 것이 더 좋다

이렇게 하면 다른 파일에 있는 데이터를 가져올 수 있다.

node.js 시스템

workThread - 실제 일을 하는 부분
ajax success : function => 콜백 함수
쌓아놓고 사용하는 것.

콜백지옥


콜백지옥에서 벗어나기 위해 promise를 사용함


promise 비동기 처리

jquery 설치하기


PS C:\java505\intellij\react\react_test2> npm install jquery

Promise.js

// Promise.js
// 제일 어렵다고 하셨음!
// 자바스크립트에서 비동기 함수의 동기 처리를 하기 위해서 사용하는 객체
// 비동기 함수와 콜백에 대한 개념이 있어야 한다

// 자바스크립트는 기본적으로 1 thread(쓰레드) 비동기 처리 방식을 사용하고 있다.

// thread란 프로그램이 실행되는 최소 단위.-> 한 줄 씩 내려가면서 실행하도록 도와줌
// 자바는 multi-thread를 제공해주고 있다 초급자는 multi-thread를 사용하면 안된다. 데드락이 일어날 수 있음
// 데드락 : 서로 연관된 걸 사용하고 있으면 서로 종료가 되지 않아 멈춰 있는 현상
// 프로그래밍 경험이 많은 사람들이 멀티스레드를 사용하는 편

// 자바스크립트에서 순차적으로 실행을 하고 싶을 경우 콜백 함수를 이용해야 한다
// 순차적으로 실행할 것이 많아지게 되면 콜백지옥이라고 불리는 형태가 만들어지게 됨
// 프로미스는 이러한 콜백 지옥을 해결하기 위해서 사용하는 객체


// react를 사용한다는 건 스프링 부트에서 데이터만 던져주고 리액트가 데이터를 받아 화면에 보여주는 형식
// 다 ajax를 사용하면서 서로 통신함 대표적인 비동기방식
// 그렇기 때문에 promise를 알아야 한다.

//프로미스에는 preding, fulfilled, rejected 3가지 상태가 존재함
// pending : 대기 상태, 비동기 함수가 실행되고, 아직 처리가 완료되지 않은 상태
// fulfilled : 완료 상태. 비동기 함수가 실행된 후 정상적으로 처리가 완료된 상태
// rejected : 거부상태, 비동기 함수가 실행된 후 오류가 발생한 상태

// 프로미스 실행 시 콜백함수가 실행되고, 해당 콜백함수의 매개변수로 resolve(), reject()라는 함수를 제공함
// resolve(매개변수) : 프로미스 실행 후 fulfilled 상태일 경우 실행하는 함수로 나중에 then()함수를 제공함
// reject(매개변수) : 프로미스 실행 후 rejected 상태일 경우 실행하는 함수로 나중에 catch() 함수를 제공함

// 프로미스에서는 완료 및 오류처리를 하기 위해서 then(), catch() 함수를 제공하고 있음
// then(매개변수) : 비동기 함수 실행이 완료된 후 실행되는 함수
// catch(매개변수) : 비동기 함수 실행이 거부된 후 실행되는 함수

// 사용법
// 선언 :
// function 프로미스를 사용할 함수명 (함수 안에 promise실행)
//   return new Promise(function(resolve, reject){
//      비동기 통신 소스..
//      비동기 통신 결과에 따라 resolve(), reject();
//    });
//  }

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

import React from "react";
import $ from "jquery";

// 프로미스 객체를 사용할 함수
function getData(){
    // 콜백 함수 선언 new Promise
    return new Promise(function(resolve,reject){
        const data = 100;

        resolve(data); //프로미스 사용 반환 값 : 100
        // reject(data); //프로미스 사용 오류 시 출력 : 100
    });
}
// resolve 하면 then 실행됨
// reject 하면 catch 실행됨
// 프로미스 사용 후 결과를 출력 // 함수 실행
getData()
    .then(function (data){
        console.log(`프로미스 사용 반환 값 : ${data}`);
    })
    .catch(function (err){
        console.log(`프로미스 사용 오류 시 출력 : ${err}`);
    });

const getData1 = function () {
    return new Promise(function (resolve, reject){
    //    import $ from "jquery"; 이거 있어야합!!

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

getData1()
    .then(function (data) {
    console.log(data);
})
    .catch(function(err) {
        console.log(err);
    });

export {getData,getData1};

App.js

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


function App() {
  getData();
  getData1()
      .then(function(data) {
          console.log(data);
      })
      .catch(function (err){
        console.log(err);
      })
  return (
    <div className="App">
    </div>
  );
}

export default App;

서버가 필요하기 때문에 스프링 부트 생성



cors 오류 : cross 오류
localhost port번호가 서로 다르기 때문에 생기는 오류
그렇기 때문에 서버에서나 리엑트에서 옵션을 넣어주면 된다

AsyncServerController

package com.bitc.reactasyncserver.Controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class AsyncServerController {

    @RequestMapping("/")
    public String index() throws Exception {
        return "index";
    }

//    localhost:3000으로 접근하는 게 있으면 이리로 보내줘라는 뜻
    @CrossOrigin(origins = "http://localhost:3000")
    @ResponseBody
    @RequestMapping(value = "/async/data1", method = RequestMethod.POST)
    public String asyncDatal() throws Exception{
        return "서버와 통신 성공";
    }
}

@CrossOrigin(origins = "http://localhost:3000")
    @ResponseBody
    @RequestMapping(value = "/async/data1", method = RequestMethod.POST)
    public String asyncDatal() throws Exception{
        return "서버와 통신 성공";
    }
}

@CrossOrigin을 추가해야한다. 의미는 localhost:3000으로 들어오면 여기로 보내라는 뜻이다.





react 페이지 f12번 누르면

componets를 들어가면

데이터가 어떻게 오고가는지 확인할 수 있다



















0개의 댓글