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);
// 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.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());
// MyMod1.js 출력할 모듈
// export로 설정 방법
// 외부로 출력하고자 하는 변수 및 함수, 클래스에 export를 접두사 붙임
// 2번 방법이 더 많이 사용되는 편이다
export const name = '아이유';
export const gender = '여성';
export const job = '가수';
export const getInfo = () => console.log(`이름 : ${name}, 직업 : ${job}, 성별 : ${gender}`);
// export로 설정방법2
// 변수, 함수, 클래스를 기존에 사용하듯이 다 선언하고, 파일의 끝에서 export를 진행
const num1 = 10;
const num2 = 20;
const sum = () => num1 + num2;
export {num1,num2,sum};
// 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로 설정바꿔도 되지만 우리는 특정 폴더에서만 사용할 것이기 때문에 파일명을 바꾸는 것이 더 좋다
이렇게 하면 다른 파일에 있는 데이터를 가져올 수 있다.
workThread - 실제 일을 하는 부분
ajax success : function => 콜백 함수
쌓아놓고 사용하는 것.
콜백지옥에서 벗어나기 위해 promise를 사용함
PS C:\java505\intellij\react\react_test2> npm install jquery
// 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};
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번호가 서로 다르기 때문에 생기는 오류
그렇기 때문에 서버에서나 리엑트에서 옵션을 넣어주면 된다
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를 들어가면
데이터가 어떻게 오고가는지 확인할 수 있다