0 React 학습 전 필수 JavaScript 문법
React(리액트) 학습 전 필수 JavaScript(자바스크립트) 문법
1. 변수 선언
var 대신 let과 const를 사용합니다. React에서는 주로 const를 사용합니다.
1// let: 재할당 가능한 변수2let age = 20;3age = 21; // 값 변경 가능4console.log(age); // 21 출력5
6// const: 재할당 불가능한 상수7const name = '철수';8// name = '영희'; // 오류 발생! const는 재할당 불가9
10// const 배열과 객체11const arr = [1, 2, 3];12arr.push(4); // 배열 내용 변경은 가능13console.log(arr); // [1, 2, 3, 4]14// arr = [5, 6]; // 오류! 배열 자체를 재할당은 불가15
16const obj = { a: 1 };17obj.a = 2; // 객체 속성 변경은 가능18obj.b = 3; // 새 속성 추가도 가능19console.log(obj); // { a: 2, b: 3 }핵심: const는 변수의 재할당을 막지만, 객체나 배열의 내용 변경은 가능합니다.
2. 화살표 함수 (Arrow Function, 애로우 펑션)
함수를 더 짧게 작성하는 방법입니다. React에서 매우 자주 사용됩니다.
2.1. 기본 문법
1// 일반 함수2function add1(a, b) {3 return a + b;4}5
6// 화살표 함수 - 기본형7const add2 = (a, b) => {8 return a + b;9};10
11// 화살표 함수 - 간단한 형태 (return과 중괄호 생략)12const add3 = (a, b) => a + b;13
14// 매개변수가 하나일 때 (소괄호 생략 가능)15const double = x => x * 2;16
17// 매개변수가 없을 때 (소괄호 필수)18const greet = () => '안녕';19
20// 객체 반환 시 소괄호로 감싸기21const getUser = id => ({ id: id, name: '철수' });22
23console.log(add3(5, 3)); // 824console.log(double(4)); // 825console.log(getUser(1)); // { id: 1, name: '철수' }2.2. 화살표 함수와 this
1// 일반 함수의 this2const user1 = {3 name: '철수',4 sayHi: function() {5 console.log('안녕 ' + this.name); // this는 user1 객체6 }7};8user1.sayHi(); // '안녕 철수'9
10// 화살표 함수의 this11const user2 = {12 name: '영희',13 sayHi: () => {14 console.log('안녕 ' + this.name); // this는 상위 스코프의 this15 }16};17user2.sayHi(); // '안녕 undefined'18
19// React 이벤트 핸들러에서 자주 사용20const button = {21 text: '클릭',22 handleClick: function() {23 // 일반 함수: bind 필요24 setTimeout(function() {25 console.log(this.text); // undefined26 }, 1000);27 },28 handleClickArrow: function() {29 // 화살표 함수: bind 불필요30 setTimeout(() => {31 console.log(this.text); // '클릭'32 }, 1000);33 }34};3. 템플릿 리터럴 (Template Literal, 템플릿 리터럴)
백틱(`)을 사용해 문자열을 만들고, $ 안에 변수나 표현식을 넣을 수 있습니다.
1const name = '철수';2const age = 20;3
4// 기존 방식5const msg1 = '이름: ' + name + ', 나이: ' + age;6
7// 템플릿 리터럴8const msg2 = `이름: ${name}, 나이: ${age}`;9
10// 표현식 사용11const msg3 = `내년 나이: ${age + 1}세`;12
13// 여러 줄 문자열14const html = `15 <div>16 <h1>${name}</h1>17 <p>${age}세</p>18 </div>19`;20
21console.log(msg2); // 이름: 철수, 나이: 204. 구조 분해 할당 (Destructuring, 디스트럭처링)
배열이나 객체의 값을 쉽게 추출합니다. React Props와 State에서 필수입니다.
1// ========== 객체 구조 분해 ==========2const user = {3 name: '철수',4 age: 20,5 job: '개발자'6};7
8// 기존 방식9const name1 = user.name; // 하나씩 추출10const age1 = user.age;11
12// 구조 분해 할당13const { name, age, job } = user; // 한 번에 추출14console.log(name); // '철수'15console.log(age); // 2016
17// 변수명 변경18const { name: userName, age: userAge } = user;19console.log(userName); // '철수'20
21// 기본값 설정22const { name: n, city = '서울' } = user;23console.log(city); // '서울' (user에 city가 없음)24
25
26// ========== 배열 구조 분해 ==========27const arr = [1, 2, 3, 4, 5];28
29// 기존 방식30const first1 = arr[0];31const second1 = arr[1];32
33// 구조 분해 할당34const [first, second] = arr; // 순서대로 추출35console.log(first); // 136console.log(second); // 237
38// 일부만 추출39const [a, , c] = arr; // 중간 값 건너뛰기 (쉼표로)40console.log(a, c); // 1 341
42// 나머지 요소43const [x, ...rest] = arr; // 첫 번째 제외하고 나머지44console.log(rest); // [2, 3, 4, 5]45
46
47// ========== 함수 매개변수에서 구조 분해 (React Props에서 자주 사용) ==========48// 기존 방식49function greet1(user) {50 console.log(`안녕 ${user.name}`);51}52
53// 구조 분해 활용54function greet2({ name, age }) { // 필요한 속성만 추출55 console.log(`안녕 ${name}, ${age}세`);56}57
58const person = { name: '철수', age: 20 };59greet2(person); // 안녕 철수, 20세60
61// 기본값과 함께 사용62function greet3({ name, age = 18 }) {63 console.log(`${name}님은 ${age}세입니다`);64}65greet3({ name: '영희' }); // 영희님은 18세입니다5. 스프레드 연산자 (Spread Operator, 스프레드 오퍼레이터)
… 을 사용해 배열이나 객체를 펼칩니다. React에서 불변성 유지에 필수입니다.
1// ========== 배열 스프레드 ==========2const arr1 = [1, 2, 3];3const arr2 = [4, 5, 6];4
5// 배열 합치기6const arr3 = [...arr1, ...arr2];7console.log(arr3); // [1, 2, 3, 4, 5, 6]8
9// 배열 복사 (새로운 배열 생성)10const copy = [...arr1];11copy.push(4);12console.log(arr1); // [1, 2, 3] (원본 그대로)13console.log(copy); // [1, 2, 3, 4]14
15// 요소 추가16const arr4 = [0, ...arr1, 4];17console.log(arr4); // [0, 1, 2, 3, 4]18
19
20// ========== 객체 스프레드 ==========21const user = { name: '철수', age: 20 };22
23// 객체 복사24const userCopy = { ...user };25
26// 속성 추가27const user2 = { ...user, job: '개발자' };28console.log(user2); // { name: '철수', age: 20, job: '개발자' }29
30// 속성 덮어쓰기31const user3 = { ...user, age: 21 };32console.log(user3); // { name: '철수', age: 21 }33
34// 여러 객체 합치기35const a = { x: 1, y: 2 };36const b = { y: 3, z: 4 };37const c = { ...a, ...b }; // y는 b의 값으로 덮어써짐38console.log(c); // { x: 1, y: 3, z: 4 }39
40
41// ========== React에서 불변성 유지 예시 ==========42// 잘못된 방식 (원본 수정)43const state = { count: 0, user: { name: '철수' } };44state.count = 1; // 원본 수정 (React에서 감지 못함)45
46// 올바른 방식 (새 객체 생성)47const newState = { ...state, count: 1 };48
49// 중첩 객체 업데이트50const newState2 = {51 ...state,52 user: { ...state.user, name: '영희' }53};6. 배열 메서드 (Array Methods, 어레이 메서드)
React에서 리스트 렌더링에 필수적인 배열 메서드들입니다.
6.1. map - 배열 변환 (가장 중요!)
1const nums = [1, 2, 3, 4, 5];2
3// 각 요소에 2를 곱한 새 배열4const doubled = nums.map(num => num * 2);5console.log(doubled); // [2, 4, 6, 8, 10]6
7// 객체 배열 변환8const users = [9 { id: 1, name: '철수' },10 { id: 2, name: '영희' }11];12const names = users.map(user => user.name);13console.log(names); // ['철수', '영희']14
15// HTML 문자열 생성 (React JSX와 유사)16const items = nums.map(num => `<li>${num}</li>`);17console.log(items); // ['<li>1</li>', '<li>2</li>', ...]18
19// React에서 사용 예시20const userList = users.map(user => ({21 id: user.id,22 displayName: user.name.toUpperCase()23}));24console.log(userList); // [{ id: 1, displayName: '철수' }, ...]6.2. forEach - 배열 순회 (반환값 없음)
1const nums = [1, 2, 3, 4, 5];2
3// forEach는 반환값이 없음 (undefined 반환)4const result1 = nums.forEach(num => {5 console.log(num); // 1, 2, 3, 4, 5 출력6});7console.log(result1); // undefined8
9// 외부 변수 수정 (부수 효과)10let sum = 0;11nums.forEach(num => {12 sum += num;13});14console.log(sum); // 1515
16// map은 새 배열 반환17const result2 = nums.map(num => num * 2);18console.log(result2); // [2, 4, 6, 8, 10]6.3. map vs forEach 비교
1const nums = [1, 2, 3];2
3// ========== map: 새 배열 생성 (React 렌더링에 사용) ==========4const doubled = nums.map(num => num * 2);5console.log(doubled); // [2, 4, 6]6
7
8// ========== forEach: 반복만 수행 (로깅, 부수효과에 사용) ==========9nums.forEach(num => {10 console.log(num * 2); // 2, 4, 6 출력 (반환값 없음)11});12
13
14// ========== 잘못된 사용 예시 ==========15const wrong = nums.forEach(num => num * 2);16console.log(wrong); // undefined (의미 없음)17
18
19// ========== 올바른 사용 ==========20// map: 데이터 변환이 필요할 때21const newArr = nums.map(num => ({ value: num }));22
23// forEach: 단순 반복 작업24nums.forEach((num, idx) => {25 console.log(`${idx}: ${num}`);26});27
28
29// ========== React 실전 예시 ==========30const users = [31 { id: 1, name: '철수', active: true },32 { id: 2, name: '영희', active: false },33 { id: 3, name: '민수', active: true }34];35
36// React에서 사용: map으로 JSX 배열 생성37const userList = users.map(user => `<li key=${user.id}>${user.name}</li>`);38
39// 단순 출력: forEach 사용40console.log('=== 사용자 목록 ===');41users.forEach(user => {42 console.log(`${user.id}. ${user.name}`);43});44
45// 체이닝 가능 여부46const activeNames = users47 .filter(user => user.active) // map은 체이닝 가능48 .map(user => user.name); // filter 후 map49console.log(activeNames); // ['철수', '민수']50
51// forEach는 체이닝 불가52// users.forEach(...).map(...); // 오류! forEach는 undefined 반환6.4. filter - 조건에 맞는 요소만 추출
1const nums = [1, 2, 3, 4, 5, 6];2
3// 짝수만 추출4const evens = nums.filter(num => num % 2 === 0);5console.log(evens); // [2, 4, 6]6
7// 객체 배열 필터링8const users = [9 { name: '철수', age: 20 },10 { name: '영희', age: 17 },11 { name: '민수', age: 25 }12];13
14const adults = users.filter(user => user.age >= 20);15console.log(adults); // [{ name: '철수', age: 20 }, { name: '민수', age: 25 }]6.5. find - 조건에 맞는 첫 번째 요소 찾기
1const users = [2 { id: 1, name: '철수' },3 { id: 2, name: '영희' },4 { id: 3, name: '민수' }5];6
7// id가 2인 사용자 찾기8const user = users.find(user => user.id === 2);9console.log(user); // { id: 2, name: '영희' }10
11// 없으면 undefined 반환12const notFound = users.find(user => user.id === 99);13console.log(notFound); // undefined6.6. reduce - 배열을 하나의 값으로 축소
1const nums = [1, 2, 3, 4, 5];2
3// 합계 구하기4const sum = nums.reduce((acc, cur) => acc + cur, 0);5// acc: 누적값(처음엔 0), cur: 현재값6console.log(sum); // 157
8// 객체로 변환9const users = ['철수', '영희', '민수'];10const obj = users.reduce((acc, name, idx) => {11 acc[idx] = name;12 return acc; // 누적값 반환 필수13}, {}); // 초기값은 빈 객체14console.log(obj); // { 0: '철수', 1: '영희', 2: '민수' }6.7. 배열 메서드 체이닝
1const nums = [1, 2, 3, 4, 5, 6];2
3// 짝수만 필터링 → 2배 → 합계4const result = nums5 .filter(num => num % 2 === 0) // [2, 4, 6]6 .map(num => num * 2) // [4, 8, 12]7 .reduce((acc, cur) => acc + cur, 0); // 248
9console.log(result); // 247. 삼항 연산자 (Ternary Operator, 터너리 오퍼레이터)
조건에 따라 값을 선택합니다. React의 조건부 렌더링에 자주 사용됩니다.
1const age = 20;2
3// 기존 방식 (if-else)4let msg1;5if (age >= 20) {6 msg1 = '성인';7} else {8 msg1 = '미성년';9}10
11// 삼항 연산자12const msg2 = age >= 20 ? '성인' : '미성년';13console.log(msg2); // '성인'14
15// 중첩 사용 (비추천 - 복잡함)16const score = 85;17const grade = score >= 90 ? 'A' :18 score >= 80 ? 'B' :19 score >= 70 ? 'C' : 'D';20console.log(grade); // 'B'21
22// React에서 사용 예시23const isLogin = true;24const message = isLogin ? '환영합니다' : '로그인 해주세요';8. 단축 평가 (Short-circuit Evaluation, 쇼트 서킷 이밸류에이션)
8.1. && 연산자 - 조건부 렌더링
1const isLogin = true;2const user = { name: '철수' };3
4// && : 왼쪽이 true면 오른쪽 실행5const msg1 = isLogin && '로그인됨';6console.log(msg1); // '로그인됨'7
8const msg2 = !isLogin && '로그인 필요';9console.log(msg2); // false10
11// React에서 자주 사용12const display = isLogin && `환영합니다, ${user.name}님`;13console.log(display); // '환영합니다, 철수님'8.2. || 연산자 - 기본값 설정
1const name1 = ''; // 빈 문자열 (falsy)2const name2 = null; // null (falsy)3const name3 = '철수'; // 문자열 (truthy)4
5// || : 왼쪽이 falsy면 오른쪽 사용6const display1 = name1 || '게스트';7const display2 = name2 || '게스트';8const display3 = name3 || '게스트';9
10console.log(display1); // '게스트'11console.log(display2); // '게스트'12console.log(display3); // '철수'8.3. Nullish Coalescing (??) - null/undefined만 체크
1const count1 = 0; // 0은 falsy지만 유효한 값2const count2 = null; // null3
4// || 사용 (문제 있음)5const result1 = count1 || 10;6console.log(result1); // 10 (잘못된 결과 - 0을 무시함)7
8// ?? 사용 (올바름)9const result2 = count1 ?? 10; // 0은 null/undefined가 아니므로 0 반환10const result3 = count2 ?? 10; // null이므로 10 반환11
12console.log(result2); // 0 (올바른 결과)13console.log(result3); // 108.4. Optional Chaining (?.) - 안전한 속성 접근
1const user1 = {2 name: '철수',3 addr: { city: '서울' }4};5const user2 = { name: '영희' }; // addr 속성 없음6
7// 기존 방식 (에러 발생 가능)8// console.log(user2.addr.city); // 오류! Cannot read property 'city' of undefined9
10// 안전한 방식11console.log(user2.addr && user2.addr.city); // undefined12
13// Optional Chaining 사용14console.log(user1.addr?.city); // '서울'15console.log(user2.addr?.city); // undefined (에러 없음)16
17// 메서드 호출에도 사용18const obj = { getName: () => '철수' };19console.log(obj.getName?.()); // '철수'20console.log(obj.getAge?.()); // undefined (메서드 없어도 에러 없음)9. Promise(프로미스)와 async/await
비동기(asynchronous, 어싱크러너스) 처리를 위한 문법입니다. API 호출에 필수입니다.
9.1. Promise 기본
1// Promise 생성2const promise = new Promise((resolve, reject) => {3 const success = true;4
5 setTimeout(() => { // 2초 후 실행6 if (success) {7 resolve('성공!'); // 성공 시8 } else {9 reject('실패!'); // 실패 시10 }11 }, 2000);12});13
14// Promise 사용15promise16 .then(result => { // 성공 시 실행17 console.log(result); // '성공!'18 })19 .catch(error => { // 실패 시 실행20 console.log(error);21 });9.2. async/await - Promise를 쉽게
1// API 호출 함수 (예시)2function fetchUser(id) {3 return new Promise(resolve => {4 setTimeout(() => {5 resolve({ id, name: '철수' });6 }, 1000);7 });8}9
10// 기존 방식 (then 사용)11fetchUser(1)12 .then(user => {13 console.log(user);14 });15
16// async/await 사용17async function getUser() { // async 함수 선언18 const user = await fetchUser(1); // await로 Promise 기다림19 console.log(user); // { id: 1, name: '철수' }20}21
22getUser();9.3. async/await 에러 처리
1async function loadData() {2 try { // 에러 처리 시작3 const res = await fetch('https://api.example.com/data');4 const data = await res.json();5 console.log(data);6 } catch (error) { // 에러 발생 시7 console.log('에러:', error);8 }9}10. 모듈 (Module, 모듈) - import/export
파일 간 코드를 공유합니다. React 컴포넌트는 모두 모듈입니다.
10.1. export - 내보내기
1// named export (이름 지정 내보내기)2export const add = (a, b) => a + b;3export const subtract = (a, b) => a - b;4
5const multiply = (a, b) => a * b;6const divide = (a, b) => a / b;7
8export { multiply, divide }; // 한 번에 내보내기9
10// default export (기본 내보내기) - 파일당 하나만11export default function greet(name) {12 return `안녕 ${name}`;13}10.2. import - 가져오기
1// named import (이름으로 가져오기)2import { add, subtract } from './utils.js';3console.log(add(5, 3)); // 84
5// 이름 변경하여 가져오기6import { multiply as mul } from './utils.js';7console.log(mul(4, 2)); // 88
9// 모두 가져오기10import * as utils from './utils.js';11console.log(utils.divide(10, 2)); // 512
13// default import (기본 가져오기)14import greet from './utils.js'; // 중괄호 없이, 원하는 이름 사용 가능15console.log(greet('철수')); // '안녕 철수'16
17// named와 default 함께18import greet, { add } from './utils.js';11. 객체 단축 속성 (Property Shorthand, 프로퍼티 쇼트핸드)
1const name = '철수';2const age = 20;3
4// ========== 단축 속성 ==========5// 기존 방식6const user1 = {7 name: name,8 age: age9};10
11// 단축 속성 (변수명과 같으면 생략 가능)12const user2 = { name, age };13console.log(user2); // { name: '철수', age: 20 }14
15
16// ========== 메서드 단축 ==========17// 기존 방식18const obj1 = {19 sayHi: function() {20 console.log('안녕');21 }22};23
24// 단축 (function 키워드 생략)25const obj2 = {26 sayHi() {27 console.log('안녕');28 }29};30
31
32// ========== 계산된 속성명 ==========33const key = 'name';34const user3 = {35 [key]: '철수', // 변수를 속성명으로 사용36 [`${key}2`]: '영희' // 표현식도 가능37};38console.log(user3); // { name: '철수', name2: '영희' }12. 자주 하는 실수와 해결법
12.1. const 객체 수정
1// 잘못된 생각2const obj = { a: 1 };3// obj = { b: 2 }; // 오류! const는 재할당 불가4
5// 올바른 방법6const obj = { a: 1 };7obj.a = 2; // 객체 속성 변경은 가능8obj.b = 3; // 새 속성 추가도 가능9console.log(obj); // { a: 2, b: 3 }12.2. 화살표 함수 객체 반환
1// 잘못된 코드 (중괄호를 코드 블록으로 인식)2const getUser = id => { id: id, name: '철수' };3console.log(getUser(1)); // undefined4
5// 올바른 코드 (소괄호로 감싸기)6const getUser = id => ({ id: id, name: '철수' });7console.log(getUser(1)); // { id: 1, name: '철수' }12.3. map에서 return 누락
1// 잘못된 코드 (중괄호 사용 시 return 필요)2const nums = [1, 2, 3];3const doubled = nums.map(num => { num * 2 });4console.log(doubled); // [undefined, undefined, undefined]5
6// 올바른 코드 1 (중괄호 없으면 자동 return)7const doubled = nums.map(num => num * 2);8
9// 올바른 코드 2 (return 명시)10const doubled = nums.map(num => { return num * 2; });12.4. forEach로 배열 생성 시도
1// 잘못된 코드 (forEach는 undefined 반환)2const nums = [1, 2, 3];3const doubled = nums.forEach(num => num * 2);4console.log(doubled); // undefined5
6// 올바른 코드 (map 사용)7const doubled = nums.map(num => num * 2);8console.log(doubled); // [2, 4, 6]13. 연습 문제
13.1. 배열 메서드 종합
다음 사용자 배열에서 20세 이상인 사용자의 이름만 추출하세요.
1const users = [2 { name: '철수', age: 17 },3 { name: '영희', age: 22 },4 { name: '민수', age: 19 },5 { name: '지영', age: 25 }6];7
8// 답:9const result = users10 .filter(user => user.age >= 20)11 .map(user => user.name);12// ['영희', '지영']13.2. 구조 분해와 스프레드
user 객체에서 name을 추출하고, 나머지를 rest 변수에 담으세요.
1const user = { name: '철수', age: 20, job: '개발자' };2
3// 답:4const { name, ...rest } = user;5console.log(name); // '철수'6console.log(rest); // { age: 20, job: '개발자' }13.3. async/await
다음 함수를 async/await으로 변환하세요.
1// 기존 코드2function getData() {3 fetch('https://api.example.com/data')4 .then(res => res.json())5 .then(data => console.log(data));6}7
8// 답:9async function getData() {10 const res = await fetch('https://api.example.com/data');11 const data = await res.json();12 console.log(data);13}13.4. map vs forEach
다음 중 어떤 메서드를 사용해야 할까요?
1const nums = [1, 2, 3, 4, 5];2
3// A. 각 숫자에 10을 더한 새 배열이 필요함4const result1 = nums.map(num => num + 10);5
6// B. 각 숫자를 콘솔에 출력만 하고 싶음7nums.forEach(num => console.log(num));14. 학습 체크리스트
React를 시작하기 전에 다음 항목들을 확인하세요:
- ✅ let과 const의 차이를 알고 있다
- ✅ 화살표 함수를 작성할 수 있다
- ✅ 화살표 함수의 this 동작을 이해한다
- ✅ 템플릿 리터럴을 사용할 수 있다
- ✅ 객체와 배열 구조 분해를 할 수 있다
- ✅ 스프레드 연산자로 복사/합치기를 할 수 있다
- ✅ map, filter, find를 사용할 수 있다
- ✅ map과 forEach의 차이를 이해한다
- ✅ 삼항 연산자와 단축 평가를 이해한다
- ✅ async/await의 기본 사용법을 안다
- ✅ import/export를 사용할 수 있다
15. 핵심 요약
React에서 가장 많이 사용하는 문법 TOP 5
- map - 리스트 렌더링
- 구조 분해 할당 - Props 추출
- 화살표 함수 - 이벤트 핸들러
- 스프레드 연산자 - 불변성 유지
- 삼항 연산자 - 조건부 렌더링
이 자료를 완전히 이해하면 React 학습이 훨씬 수월해집니다!