한 개의 페이지로 이루어진 어플리케이션. MPA (Multi Page Application)과 상반된 개념
SPA
MPA
컴포넌트란? 쉽게 말하면 페이지를 이루는 단위 (Header, Footer, Contents 등)
React에서는 컴포넌트를 조립해서 페이지를 만든다 !
이전에는 var 키워드로 변수를 선언했다면 ES6부턴 let, const 키워드를 사용해 변수, 상수를 선언한다.
- var : 재할당 가능, 재선언 가능, 함수 레벨 스코프
- let : 재할당 가능, 재선언 불가, 블록 레벨 스코프
- const : 재할당 불가, 재선언 불가, 블록 레벨 스코프
객체는 key-value 쌍으로 가짐
// 객체 선언 방법
const a = {
name: 'abc',
age: 1
}
const name = 'Jaehyun'
const b = {
name, // 객체 키와 동일한 이름을 가진 변수를 적용할 때, 단축 속성을 사용할 수 있음
age: 1
}
객체나 배열을 복사할 때 참조까지 복사하느냐의 차이
얕은 복사
변수에 객체, 배열, 함수와 같은 참조 타입 데이터를 담을 때, 변수에는 데이터가 담기는 것이 아닌, 데이터의 메모리 주소(참조값)가 저장됨
const user = {
name: "재현",
address: { city: "Seoul" }
};
// 얕은 복사 (스프레드 연산자)
const copy = { ...user };
copy.name = "길동";
copy.address.city = "Busan";
console.log(user.name); // "재현" (독립적)
console.log(user.address.city); // "Busan" (같이 바뀜!)
// name은 기본값이라 독립적이지만, address는 객체가 참조값을 공유 => 원본도 같이 변경됨
깊은 복사
const user = {
name: "재현",
address: { city: "Seoul" }
};
// 깊은 복사 (JSON 방법)
const deepCopy = JSON.parse(JSON.stringify(user));
deepCopy.name = "길동";
deepCopy.address.city = "Busan";
console.log(user.name); // "재현"
console.log(user.address.city); // "Seoul" (안 바뀜!)
// 두 객체는 독립적이므로 서로 영향을 주지 않음
백틱 (``)을 사용하여 문자열을 선언하는 방식.
// 객체 구조 분해 할당
const person = {
name: 'Jaehyun',
age: 1
}
const {name: userName, age} = person
console.log(`${userName}님, ${age}살이시네요!`); // Jaehyun님, 1살이시네요!
function hello({name, age}) {
console.log(`${name}님, ${age}살이시네요!`);
}
hello(person); // Jaehyun님, 1살이시네요!
// 배열 구조 분해 할당
const testArr = [1, 2, 3, 4, 5];
const [val1, val2, val3, val4, val5] = testArr;
console.log(val1); // 1
let [name] = ["Tom", 10, "Seoul"];
let [, age] = ["Tom", 10, "Seoul"]; // Tom은 무시됨
let [name, age, region] = ["Tom", 10, "Seoul"];
let [name, age, region, height] = ["Tom", 10, "Seoul"]; // height는 undefined
let [name, age, region, height = 150] = ["Tom", 10, "Seoul"];
스프레드 연산자(...)는 배열, 객체, 이터러블의 요소를 펼치는 연산자. 배열, 객체, 함수 호출 등의 상황에서 자주 쓰임
const arr1 = [1, 2, 3];
const arr2 = [4, 5];
const merged = [...arr1, ...arr2];
console.log(merged); // [1, 2, 3, 4, 5]
// 복사
const obj1 = { name: "Jaehyun", age: 1 };
const obj2 = { region: "Seoul", age: 3 };
const merged = { ...obj1, ...obj2 };
console.log(merged); // { name: "Jaehyun", age: 3, region: "Seoul" }
// 나중에 오는 속성이 앞에 있는 속성을 덮어씀
function sum(...args) {
return args.reduce((acc, cur) => acc + cur);
}
console.log(sum(10, 20, 30)); // 60
console.log(sum(1, 2, 3, 4, 5)); // 15
// 스프레드 연산자 사용으로 가변 인자를 전달할 수 있음
=>
사용
// 일반 함수 표현식
const add = function(a, b) {
return a + b;
};
// 화살표 함수
const add = (a, b) => {
return a + b;
};
// 생성자 함수로 사용 불가 예시
const Person = (name) => {
this.name = name;
};
const p = new Person("abc"); // ❌ TypeError
JSX(JS + XML) :JS를 확장한 문법으로 JS 파일 내부에서 HTML 문법을 사용있는 문법
부모 컴포넌트가 자식 컴포넌트로 넘겨준 데이터를 props
라고 함 (컴포넌트 간 state 공유 방법)
최상위 컴포넌트에서 최하위 컴포넌트로 props를 넘겨주어야 할 때 중간에 의미 없이 props를 받아 그대로 넘기는
현상이 많아지는 것을 말함
컴포넌트 태그 사이에 들어가는 내용을 의미,
const Card = ({children}) => {
return <div className="card">{children}</div>;
}
// 사용 예시
<Card>
<h1>제목</h1>
<p>내용</p>
</Card>
const Card = (props) => {
return <div>{props.name}</div>;
}
// 사용 예시
<Card name='Ahn' />
구조 분해 할당을 적용해보면
const Card = ({name}) => {
return <div>{name}</div>;
}
// 사용 예시
<Card name='Ahn' />
로 사용 가능
컴포넌트에 props가 전달되지 않았을 때 사용할 기본값을 지정하는 개념
const Card = ({name}) => {
return <div>{name}</div>;
}
Card.defaultProps = {
name: 'Ahn'
}
const Card = ({ name = 'Ahn' }) => {
return <div>{name}</div>;
}