React
2020년08월05일에듀캐스트 장고&리액트 강의를 듣고 정리하는 글이다.
패키지 관리자
- npm (node package manager): nodejs 기본 패키지 관리자
- npm install –global 패키지명: 디폴트가 로컬에 설치되기에 전역 설치를 위해 global 옵션 사용(파이썬은 반대이며 가상환경으로 해결한다.)
- npm install 패키지명
- yarn: 페이스북 주도로 개발된 패키지 관리자 [설치] npm install –global yarn
yarn global add 패키지명 yarn add global 패키지명 -> global 이름의 패키지가 설치되는 것이니 조심하자 yarn add 패키지명 yarn add –dev 패키지명: 개발용으로 설치하고 싶을때 yarn add
이 실습에서는 yarn을 통해서 react를 설치해 볼 것이다.
[react 설치]
프로젝트 디렉토리를 만들 위치로 이동해서 다음과 같은 명령어를 입력해주자.
yarn create react-app "프로젝트명"
시간이 좀 걸리니 찬찬히 기다려주면 완료된다.
완료가 되고 cd “프로젝트명”으로 들어가보면 git이 init 되어있다.
ES6 문법
- let과 const: 이 타입이 생기기전에는 우리는 var로 변수를 선언해서 사용했을 것이다.
var name = 'hsj';
console.log(name);
이렇게 했을 시 문제 없이 출력이 될 것이다.
console.log(name);
var name = 'hsj';
console.log(name);
이렇게 하면 undefiend와 hsj가 출력이 될 것이다. 이렇게 되는 이유는 javascript는 호이스팅이라고 해서 선언한 변수명이 맨 위로 올라간다고 하는데, 이렇게 name은 참조하는 것이 없기 때문에 undefiend가 출력이 되는 것이다. ES6부터는 var대신 let을 사용하면 위의 혼란스러움을 해결할 수 있다. const는 상수값을 선언하는 것이기에 필히 선언할때 값을 입력해주자.
객체 복사
JS는 Object/Array에 대해서는 대입 시에 얕은 복사가 이루어 진다. 얕은 복사는 참조값이 같기에 어느 한쪽에서 수정하면 다른 변수로 출력해도 같은 값이 표시된다.
const obj1 = { value: 10};
const obj2 = obj1;
const obj3 = JSON.parse(JSON.stringify(obj1)); // 깊은 복사
obj1.value1 += 1;
console.log('obj11:', obj1); // 11
console.log('obj11:', obj2); // 11
console.log('obj11:', obj3); // 10
여러 줄 선언, 표현식
백쿼터( ` )를 사용해서 여러줄을 표현할 수 있고 ${}를 사용해서 변수나 함수 등을 입력받을 수 있다..
const name = 'hsj';
const text = `
줄1
줄2
${name};
`
배열 비구조화 (Array Destructuring)
리액트에서 자주 쓰는 문법
let [name] = ["Tom", 10, "Seoul"]; // "Tom" 저장
let [,age,] = ["Tom", 10, "Seoul"]; // 10이 저장
let [name, age, region, height] = ["Tom", 10, "Seoul"] // height는 undefiend이 할당. 파이썬이었으면 ValueError 예외가 발생한다.
let [name, age, region, height=150] = ["Tom", 10, "Seoul"] // 디폴트값을 할당할 수 있다.
function get_default_height() {
console.log("get_default_height() 호출")
return 150;
}
let [name, age, region, height=get_default_height()] = ["Tom", 10, "Seoul"] // 실제 디폴트값 할당이 필요할 때 호출된다.
객체 비구조화 (Object Destructuring)
이것 또한 자주 쓰이는 문법이라 한다.
const tom = {
name: "Tom",
age: 10,
region: "Seoul"
};
const {age, name, height} = tom; // 객체에서 있는 값 가져가고, 없으면 undefiend
const print_person1 = (person) => {
console.log(person.name);
};
const print_person2 = ({name}) => {
console.log(name);
};
print_person1(tom); // 이름 출력
print_person2(tom); // 마찬가지로 이름이 출력된다.
const people = [
{name: 'Tom', age:10, region: 'Seoul'},
{name: 'Steve', age:12, region: 'Pusan'}
];
for (const person of people){
console.log(person.name, person.age);
}
for (const {name, age} of people){
console.log(name, age);
}
const person = {
name: 'Tom',
age: 10,
region: {
country: '서울',
postcode: '06222',
}
};
const {name, region: {postcode}} = person;
console.log(name, postcode);
전개 연산자(Spread Operator)
파이썬의 *과 ** pack, unpack과 유사하다.
let [name, ...rest] = ["Tom", 10, "Seoul"]; // "Tom"을 제외하고 rest 배열에 할당
let names = ["Steve", "John"]
let students = ["Tom", ...names, ...names]; // names배열을 unpack
let printArgs = (...args) => {
console.log(args);
}
// 리액트에서 정말 많이 사용된다고 한다.
let tom = {
name: "Tom",
age: 10,
region: "Seoul"
};
// 속성명이 중복되는 경우, 마지막 값이 남는다.
let steve = {
...tom,
name: "Steve"
}
const numbers = [1, 3, 5, 7, 9];
Math.max(numbers) // Nan 출력, max함수는 인자들을 받아서 사용하기 때문에 아래처럼 풀어줘야 한다.
Math.max(...numbers)
함수 / Default Parameters
모든 타입의 값들을 디폴트 파라미터로 지정할 수 있다.
- 파이썬에서는 Immutable 값들만 디폴트 파라미터로 지정 가능
```javascript
function hello(name=”Tom”, age=10){
console.log(
나는 ${name}. ${age}살이다.
); }
const get_default_age = () => 10 // () 인자, => 이후는 return
function hello(name=”Tom”, age=get_default_age()){
console.log(나는 ${name}. ${age}살이다.
);
}
console.log(hello(“Steve”))
### 함수 / Named Parameters
객체 비구조화를 활용한다.
```javascript
function print_person1(name, age, region){
console.log('1>', name, age, region);
}
print_person1('Tom', 10, 'Seoul') // 순서대로 인자에 들어간다.
// 아래 방식을 많이 사용한다.
function print_person2({name, age, region}) {
console.log('2>', name, age, region);
}
print_person2({name: 'Tom', age: 10, region: 'Seoul'})
함수 / Arrow function
return을 사용하지 않아도, 계산된 값을 반환한다. 인자가 1개일 경우, 소괄호 생략 가능하다.
var hello1 = function(name, age){
return `Hello. I'm ${name}. ${age}`;
};
const fn = x => x+ 10;
let hello2 = (name, age) => `Hello ${name} ${age}` // 중괄호 없고, return 값 없이도 사용할 수 있다.
let hello3 = (name, age) => {
return `Hello ${name} ${age}`;
};
this와 arguments를 바인딩 하지 않는다. Arrow 함수를 사용하면 this의 값이 바뀌지 않는다.
var tom = {
name: "Tom",
print1: function() {
console.log(`[print1-1] name: ${this.name}`);
(function(){
console.log(`[print1-2] name: ${this.name}`);
})();
},
print2: function(){
console.log(`[print2-1] name : ${this.name}`);
var me = this;
(function(){
console.log(`[print2-2] name : ${me.name}`);
})();
},
print3: function() {
console.log(`[print3-1] name : ${this.name}`);
(()=>{
console.log(`print[3-2] name : ${this.name}`);
})();
}
}
함수의 다양한 형태
const mysum1 = (x, y) => x + y;
const mysum2 = (x, y) => {x, y} // 객체 생성 key, value가 같으면 이처럼 사용해도 된다.
const mysum3 = (x, y) => ({x: x, y: y});
const mysum4 = (x, y) => {
return {x; x, y: y};
}
const mysum5 = function(x, y){
return {x: x, y: y};
}
function mysum6(x, y){
return {x: x, y: y};
}
콜백지옥
콜백함수는 요즘 지양함. Promise, async/await 사용
클래스와 상속
- ES6 이전 ```javascript function Person(name, age){ this.name = name; this.age = age; } Person.prototype.print = function(){ console.log(this.name + “, “ + this.age); }
var tom = new Person(“Tom”, 10); tom.print();
- ES6 이후
```javascript
// 문법이 다를 뿐, 여전히 prototpye을 사용한다.
class Person {
constructor(name, age){
this.name = name;
this.age = age;
}
print() {
console.log(this.name + ", " + this.age);
}
}
const tom = new Person("Tom", 10);
tom.print()
// 상속
class Developer extends Person {
constructor(name, age, field){
super(name, age);
this.field = field;
}
print() {
super.print();
console.log(`field : ${this.field}`);
}
}
모듈 시스템
- 예전 웹 상의 자바스크립트에서는 script 태그를 통해서만 로딩했다.
- 모두 전역 객체에 바인딩
- 지금은 2가지 모듈 시스템이 있다.
- CommonJS Module : nodejs에서 주로 활용 ```javascript // my_module.js const name = “tom”; const age = 10;
module.exports = { name, age, region: “Seoul” };
// in_nodejs.js const my_module = require(“./my_module”); // require 문법을 사용 console.log(name);
- ES6 Module : 리액트에서 주로 활용 ```javascript // my_module_es6.js const name = "tom"; const age = 10; export default { name, age, region: "Seoul" }; export { name, }; // in_react.js import my_module from "./my_module" // default를 참조 import { name } from "./my_module" // export를 참조
고차 함수 (Hig Order Function)
함수를 인자로 받거나 반환이 가능하고, 다른 함수를 조작하는 함수. 함수/클래스 역시 모두 객체이다.
// #1
function base_10(fn){
function wrap(x, y){
return fn(x, y) + 10;
}
return wrap;
}
function mysum(x, y){
return x + y;
}
mysum = base_10(mysum);
console.log(mysum(1, 2));
// #2
const base_10 = fn => (x, y) => fn(x, y) + 10;
let mysum = (x, y) => x + y;
mysum = base_10(mysum);
console.log(mysum(1, 2));
def base_10(fn):
def wrapper(x, y):
return fn(x, y) + 10
return wrapper
def mysum(x, y):
return x + y
mysum = base_10(mysum)
print(mysum(1, 2))