React

에듀캐스트 장고&리액트 강의를 듣고 정리하는 글이다.

패키지 관리자

  • 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))