01- React 학습 전 필수 JavaScript 문법
React(리액트) 학습 전 필수 JavaScript(자바스크립트) 문법
섹션 제목: “React(리액트) 학습 전 필수 JavaScript(자바스크립트) 문법”1. 변수 선언: let, const
섹션 제목: “1. 변수 선언: let, const”var 대신 let과 const를 사용합니다. React에서는 주로 const를 사용합니다.
예제 1: let과 const의 차이
섹션 제목: “예제 1: let과 const의 차이” let age = 20; // let: 재할당 가능한 변수 age = 21; // 값 변경 가능 console.log(age); // 21 출력
const name = '철수'; // const: 재할당 불가능한 상수 // name = '영희'; // 오류 발생! const는 재할당 불가
const arr = [1, 2, 3]; // const 배열 arr.push(4); // 배열 내용 변경은 가능 console.log(arr); // [1, 2, 3, 4] // arr = [5, 6]; // 오류! 배열 자체를 재할당은 불가핵심: const는 변수의 재할당을 막지만, 객체나 배열의 내용 변경은 가능합니다.
2. 화살표 함수 (Arrow Function, 애로우 펑션)
섹션 제목: “2. 화살표 함수 (Arrow Function, 애로우 펑션)”함수를 더 짧게 작성하는 방법입니다. React에서 매우 자주 사용됩니다.
예제 2: 일반 함수 vs 화살표 함수
섹션 제목: “예제 2: 일반 함수 vs 화살표 함수”// 일반 함수function add1(a, b) { // function 키워드 사용 return a + b; // return 명시}// 화살표 함수 - 기본형const add2 = (a, b) => { // => 사용 return a + b; // return 명시};
// 화살표 함수 - 간단한 형태 const add3 = (a, b) => a + b; // 한 줄이면 return과 중괄호 생략 가능
// 매개변수가 하나일 때 const double = x => x * 2; // 소괄호도 생략 가능
// 매개변수가 없을 때 const greet = () => '안녕'; // 소괄호 필수
console.log(add3(5, 3)); // 8 console.log(double(4)); // 8예제 3: 화살표 함수와 this
섹션 제목: “예제 3: 화살표 함수와 this”const user = { name: '철수', sayHi1: function() { // 일반 함수 console.log('안녕 ' + this.name); // this는 user 객체 }, sayHi2: () => { // 화살표 함수 console.log('안녕 ' + this.name); // this는 상위 스코프의 this }};
user.sayHi1(); // '안녕 철수' user.sayHi2(); // '안녕 undefined' (React에서는 class component에서 주의)3. 템플릿 리터럴 (Template Literal, 템플릿 리터럴)
섹션 제목: “3. 템플릿 리터럴 (Template Literal, 템플릿 리터럴)”백틱(`)을 사용해 문자열을 만들고, $ 안에 변수나 표현식을 넣을 수 있습니다.
예제 4: 템플릿 리터럴 활용
섹션 제목: “예제 4: 템플릿 리터럴 활용”1. const name = '철수';2. const age = 20;3.4. // 기존 방식5. const msg1 = '이름: ' + name + ', 나이: ' + age; // 문자열 연결6.7. // 템플릿 리터럴8. const msg2 = `이름: ${name}, 나이: ${age}`; // 백틱과 ${} 사용9.10. // 표현식 사용 가능11. const msg3 = `내년 나이: ${age + 1}세`; // 계산식 가능12.13. // 여러 줄 문자열14. const html = `15. <div>16. <h1>${name}</h1>17. <p>${age}세</p>18. </div>19. `; // 여러 줄 작성 가능20.21. console.log(msg2); // 이름: 철수, 나이: 204. 구조 분해 할당 (Destructuring, 디스트럭처링)
섹션 제목: “4. 구조 분해 할당 (Destructuring, 디스트럭처링)”배열이나 객체의 값을 쉽게 추출합니다. React Props와 State에서 필수입니다.
예제 5: 객체 구조 분해
섹션 제목: “예제 5: 객체 구조 분해”const user = { name: '철수', age: 20, job: '개발자'};// 기존 방식const name1 = user.name; // 하나씩 추출const age1 = user.age;
// 구조 분해 할당 const { name, age, job } = user; // 한 번에 추출 console.log(name); // '철수' console.log(age); // 20
// 변수명 변경 const { name: userName, age: userAge } = user; // 다른 이름으로 추출 console.log(userName); // '철수'
// 기본값 설정 const { name, city = '서울' } = user; // city가 없으면 '서울' 사용 console.log(city); // '서울'예제 6: 배열 구조 분해
섹션 제목: “예제 6: 배열 구조 분해” const arr = [1, 2, 3, 4, 5];// 기존 방식const first1 = arr[0]; // 인덱스로 접근const second1 = arr[1];// 구조 분해 할당const [first, second] = arr; // 순서대로 추출console.log(first); // 1 console.log(second); // 2
// 일부만 추출 const [a, , c] = arr; // 중간 값 건너뛰기 (쉼표로) console.log(a, c); // 1 3
// 나머지 요소 const [x, ...rest] = arr; // 첫 번째 제외하고 나머지 console.log(rest); // [2, 3, 4, 5]예제 7: 함수 매개변수에서 구조 분해 (React Props에서 자주 사용)
섹션 제목: “예제 7: 함수 매개변수에서 구조 분해 (React Props에서 자주 사용)” // 기존 방식 function greet1(user) { // 객체를 통째로 받음 console.log(`안녕 ${user.name}`); }
// 구조 분해 활용 function greet2({ name, age }) { // 필요한 속성만 추출 console.log(`안녕 ${name}, ${age}세`); }
const user = { name: '철수', age: 20 }; greet2(user); // 안녕 철수, 20세5. 스프레드 연산자 (Spread Operator, 스프레드 오퍼레이터)
섹션 제목: “5. 스프레드 연산자 (Spread Operator, 스프레드 오퍼레이터)”… 을 사용해 배열이나 객체를 펼칩니다. React에서 불변성 유지에 필수입니다.
예제 8: 배열 스프레드
섹션 제목: “예제 8: 배열 스프레드”const arr1 = [1, 2, 3];const arr2 = [4, 5, 6];// 배열 합치기const arr3 = [...arr1, ...arr2]; // arr1과 arr2를 펼쳐서 합침console.log(arr3); // [1, 2, 3, 4, 5, 6]// 배열 복사const copy = [...arr1]; // 새로운 배열 생성 (원본 유지) copy.push(4); // 복사본만 변경 console.log(arr1); // [1, 2, 3] (원본 그대로) console.log(copy); // [1, 2, 3, 4]
// 요소 추가 const arr4 = [0, ...arr1, 4]; // 앞뒤로 요소 추가 가능 console.log(arr4); // [0, 1, 2, 3, 4]예제 9: 객체 스프레드
섹션 제목: “예제 9: 객체 스프레드”const user = { name: '철수', age: 20 };// 객체 복사const copy = { ...user }; // 새로운 객체 생성// 속성 추가const user2 = { ...user, job: '개발자' }; // 기존 속성 + 새 속성console.log(user2); // { name: '철수', age: 20, job: '개발자' } // 속성 덮어쓰기 const user3 = { ...user, age: 21 }; // age만 변경 console.log(user3); // { name: '철수', age: 21 }
// 여러 객체 합치기 const a = { x: 1, y: 2 }; const b = { y: 3, z: 4 }; const c = { ...a, ...b }; // y는 b의 값으로 덮어써짐 console.log(c); // { x: 1, y: 3, z: 4 }6. 배열 메서드 (Array Methods, 어레이 메서드)
섹션 제목: “6. 배열 메서드 (Array Methods, 어레이 메서드)”React에서 리스트 렌더링에 필수적인 배열 메서드들입니다.
예제 10: map - 배열 변환 (가장 중요!)
섹션 제목: “예제 10: map - 배열 변환 (가장 중요!)”const nums = [1, 2, 3, 4, 5];// 각 요소에 2를 곱한 새 배열const doubled = nums.map(num => num * 2); // 각 요소를 변환console.log(doubled); // [2, 4, 6, 8, 10]// 객체 배열 변환const users = [ { id: 1, name: '철수' }, { id: 2, name: '영희' } ];
const names = users.map(user => user.name); // name만 추출 console.log(names); // ['철수', '영희']
// HTML 문자열 생성 (React와 유사) const items = nums.map(num => `<li>${num}</li>`); // 각 숫자를 li로 변환 console.log(items); // ['<li>1</li>', '<li>2</li>', ...]예제 11: forEach - 배열 순회 (반환값 없음)
섹션 제목: “예제 11: forEach - 배열 순회 (반환값 없음)”const nums = [1, 2, 3, 4, 5];// forEach는 반환값이 없음 (undefined 반환)const result1 = nums.forEach(num => { console.log(num); // 1, 2, 3, 4, 5 출력});console.log(result1); // undefined// 외부 변수 수정 (부수 효과) let sum = 0; nums.forEach(num => { sum += num; // 외부 변수 변경 }); console.log(sum); // 15
// map은 새 배열 반환 const result2 = nums.map(num => num * 2); console.log(result2); // [2, 4, 6, 8, 10]예제 12: map vs forEach 비교
섹션 제목: “예제 12: map vs forEach 비교”const nums = [1, 2, 3];// map: 새 배열 생성 (React 렌더링에 사용)const doubled = nums.map(num => num * 2); // 새 배열 반환console.log(doubled); // [2, 4, 6]// forEach: 반복만 수행 (로깅, 부수효과에 사용)nums.forEach(num => { console.log(num * 2); // 2, 4, 6 출력 (반환값 없음) });
// 잘못된 사용 예시 const wrong = nums.forEach(num => num * 2); // 의미 없음 console.log(wrong); // undefined
// 올바른 사용 // map: 데이터 변환이 필요할 때 const newArr = nums.map(num => ({ value: num })); // 객체 배열로 변환
// forEach: 단순 반복 작업 nums.forEach((num, idx) => { console.log(`${idx}: ${num}`); // 인덱스와 함께 출력 });예제 13: map과 forEach 실전 비교
섹션 제목: “예제 13: map과 forEach 실전 비교”const users = [ { id: 1, name: '철수', active: true }, { id: 2, name: '영희', active: false }, { id: 3, name: '민수', active: true }];// React에서 사용: map으로 JSX 배열 생성const userList = users.map(user => `<li>${user.name}</li>`);console.log(userList); // ['<li>철수</li>', '<li>영희</li>', '<li>민수</li>']
// 단순 출력: forEach 사용 console.log('=== 사용자 목록 ==='); users.forEach(user => { console.log(`${user.id}. ${user.name}`); // 콘솔 출력만 });
// 체이닝 가능 여부 const activeNames = users .filter(user => user.active) // map은 체이닝 가능 .map(user => user.name); // filter 후 map console.log(activeNames); // ['철수', '민수']
// forEach는 체이닝 불가 // users.forEach(...).map(...); // 오류! forEach는 undefined 반환예제 14: filter - 조건에 맞는 요소만 추출
섹션 제목: “예제 14: filter - 조건에 맞는 요소만 추출”const nums = [1, 2, 3, 4, 5, 6];// 짝수만 추출const evens = nums.filter(num => num % 2 === 0); // 조건이 true인 것만console.log(evens); // [2, 4, 6]// 객체 배열 필터링const users = [ { name: '철수', age: 20 }, { name: '영희', age: 17 }, { name: '민수', age: 25 } ];
const adults = users.filter(user => user.age >= 20); // 성인만 console.log(adults); // [{ name: '철수', age: 20 }, { name: '민수', age: 25 }]예제 15: find - 조건에 맞는 첫 번째 요소 찾기
섹션 제목: “예제 15: find - 조건에 맞는 첫 번째 요소 찾기”const users = [ { id: 1, name: '철수' }, { id: 2, name: '영희' }, { id: 3, name: '민수' }];// id가 2인 사용자 찾기const user = users.find(user => user.id === 2); // 첫 번째 일치 항목console.log(user); // { id: 2, name: '영희' }
// 없으면 undefined 반환 const notFound = users.find(user => user.id === 99); console.log(notFound); // undefined예제 16: reduce - 배열을 하나의 값으로 축소
섹션 제목: “예제 16: reduce - 배열을 하나의 값으로 축소”const nums = [1, 2, 3, 4, 5];// 합계 구하기const sum = nums.reduce((acc, cur) => acc + cur, 0);// acc: 누적값(처음엔 0), cur: 현재값console.log(sum); // 15// 객체로 변환const users = ['철수', '영희', '민수']; const obj = users.reduce((acc, name, idx) => { acc[idx] = name; // 인덱스를 키로 사용 return acc; // 누적값 반환 필수 }, {}); // 초기값은 빈 객체 console.log(obj); // { 0: '철수', 1: '영희', 2: '민수' }예제 17: 배열 메서드 체이닝
섹션 제목: “예제 17: 배열 메서드 체이닝”1. const nums = [1, 2, 3, 4, 5, 6];2.3. // 짝수만 필터링 → 2배 → 합계4. const 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.9. console.log(result); // 247. 삼항 연산자 (Ternary Operator, 터너리 오퍼레이터)
섹션 제목: “7. 삼항 연산자 (Ternary Operator, 터너리 오퍼레이터)”조건에 따라 값을 선택합니다. React의 조건부 렌더링에 자주 사용됩니다.
예제 18: 삼항 연산자 기본
섹션 제목: “예제 18: 삼항 연산자 기본” const age = 20;
// 기존 방식 (if-else) let msg1; if (age >= 20) { msg1 = '성인'; } else { msg1 = '미성년'; }
// 삼항 연산자 const msg2 = age >= 20 ? '성인' : '미성년'; // 조건 ? 참일때 : 거짓일때 console.log(msg2); // '성인'
// 중첩 사용 (비추천 - 복잡함) const score = 85; const grade = score >= 90 ? 'A' : score >= 80 ? 'B' : score >= 70 ? 'C' : 'D'; console.log(grade); // 'B'8. 단축 평가 (Short-circuit Evaluation, 쇼트 서킷 이밸류에이션)
섹션 제목: “8. 단축 평가 (Short-circuit Evaluation, 쇼트 서킷 이밸류에이션)”예제 19: && 연산자 - 조건부 렌더링
섹션 제목: “예제 19: && 연산자 - 조건부 렌더링”const isLogin = true;const user = { name: '철수' };// && : 왼쪽이 true면 오른쪽 실행const msg1 = isLogin && '로그인됨'; // isLogin이 true이므로 '로그인됨' 반환console.log(msg1); // '로그인됨'const msg2 = !isLogin && '로그인 필요'; // false이므로 false 반환console.log(msg2); // false
// React에서 자주 사용 const display = isLogin && `환영합니다, ${user.name}님`; console.log(display); // '환영합니다, 철수님'예제 20: || 연산자 - 기본값 설정
섹션 제목: “예제 20: || 연산자 - 기본값 설정”const name1 = ''; // 빈 문자열 (falsy)const name2 = null; // null (falsy)const name3 = '철수'; // 문자열 (truthy)// || : 왼쪽이 falsy면 오른쪽 사용const display1 = name1 || '게스트'; // ''는 falsy이므로 '게스트'const display2 = name2 || '게스트'; // null은 falsy이므로 '게스트'const display3 = name3 || '게스트'; // '철수'는 truthy이므로 '철수' console.log(display1); // '게스트' console.log(display3); // '철수'예제 21: Nullish Coalescing (??) - null/undefined만 체크
섹션 제목: “예제 21: Nullish Coalescing (??) - null/undefined만 체크”const count1 = 0; // 0은 falsy지만 유효한 값const count2 = null; // null// || 사용 (문제 있음)const result1 = count1 || 10; // 0은 falsy이므로 10 반환 (의도와 다름)console.log(result1); // 10 (잘못된 결과)// ?? 사용 (올바름)const result2 = count1 ?? 10; // 0은 null/undefined가 아니므로 0 반환 const result3 = count2 ?? 10; // null이므로 10 반환
console.log(result2); // 0 (올바른 결과) console.log(result3); // 10예제 22: Optional Chaining (?.) - 안전한 속성 접근
섹션 제목: “예제 22: Optional Chaining (?.) - 안전한 속성 접근”const user1 = { name: '철수', addr: { city: '서울' }};const user2 = { name: '영희' }; // addr 속성 없음
// 기존 방식 (에러 발생 가능)// console.log(user2.addr.city); // 오류! Cannot read property 'city' of undefined
// 안전한 방식 console.log(user2.addr && user2.addr.city); // undefined (에러 없음)
// Optional Chaining 사용 console.log(user1.addr?.city); // '서울' console.log(user2.addr?.city); // undefined (에러 없음)
// 메서드 호출에도 사용 const obj = { getName: () => '철수' }; console.log(obj.getName?.()); // '철수' console.log(obj.getAge?.()); // undefined (메서드 없어도 에러 없음)9. Promise(프로미스)와 async/await
섹션 제목: “9. Promise(프로미스)와 async/await”비동기(asynchronous, 어싱크러너스) 처리를 위한 문법입니다. API 호출에 필수입니다.
예제 23: Promise 기본
섹션 제목: “예제 23: Promise 기본”// Promise 생성const promise = new Promise((resolve, reject) => { const success = true;
setTimeout(() => { // 2초 후 실행 if (success) { resolve('성공!'); // 성공 시 } else { reject('실패!'); // 실패 시 } }, 2000); });
// Promise 사용 promise .then(result => { // 성공 시 실행 console.log(result); // '성공!' }) .catch(error => { // 실패 시 실행 console.log(error); });예제 24: async/await - Promise를 쉽게
섹션 제목: “예제 24: async/await - Promise를 쉽게”// API 호출 함수 (예시)function fetchUser(id) { // Promise를 반환하는 함수 return new Promise(resolve => { setTimeout(() => { resolve({ id, name: '철수' }); }, 1000); });}
// 기존 방식 (then 사용) fetchUser(1) .then(user => { console.log(user); });
// async/await 사용 async function getUser() { // async 함수 선언 const user = await fetchUser(1); // await로 Promise 기다림 console.log(user); // { id: 1, name: '철수' } }
getUser(); // 함수 호출예제 25: async/await 에러 처리
섹션 제목: “예제 25: async/await 에러 처리” async function loadData() { try { // 에러 처리 시작 const res = await fetch('https://api.example.com/data'); const data = await res.json(); // JSON 변환 기다림 console.log(data); } catch (error) { // 에러 발생 시 console.log('에러:', error); } }10. 모듈 (Module, 모듈) - import/export
섹션 제목: “10. 모듈 (Module, 모듈) - import/export”파일 간 코드를 공유합니다. React 컴포넌트는 모두 모듈입니다.
예제 26: export - 내보내기
섹션 제목: “예제 26: export - 내보내기”// utils.js// named export (이름 지정 내보내기)export const add = (a, b) => a + b; // export 붙이기export const subtract = (a, b) => a - b;
const multiply = (a, b) => a * b;const divide = (a, b) => a / b;
export { multiply, divide }; // 한 번에 내보내기
// default export (기본 내보내기) - 파일당 하나만 export default function greet(name) { // default는 하나만 가능 return `안녕 ${name}`; }예제 27: import - 가져오기
섹션 제목: “예제 27: import - 가져오기”// main.js// named import (이름으로 가져오기)import { add, subtract } from './utils.js'; // 중괄호 사용console.log(add(5, 3)); // 8
// 이름 변경하여 가져오기import { multiply as mul } from './utils.js'; // as로 이름 변경console.log(mul(4, 2)); // 8
// 모두 가져오기 import * as utils from './utils.js'; // * 사용 console.log(utils.divide(10, 2)); // 5
// default import (기본 가져오기) import greet from './utils.js'; // 중괄호 없이, 원하는 이름 사용 가능 console.log(greet('철수')); // '안녕 철수'
// named와 default 함께 import greet, { add } from './utils.js'; // default를 먼저11. 객체 단축 속성 (Property Shorthand, 프로퍼티 쇼트핸드)
섹션 제목: “11. 객체 단축 속성 (Property Shorthand, 프로퍼티 쇼트핸드)”예제 28: 객체 단축 문법
섹션 제목: “예제 28: 객체 단축 문법”const name = '철수';const age = 20;
// 기존 방식const user1 = { name: name, // 속성명과 변수명이 같음 age: age};
// 단축 속성 const user2 = { name, age }; // 변수명과 같으면 생략 가능 console.log(user2); // { name: '철수', age: 20 }
// 메서드 단축 const obj1 = { sayHi: function() { // 기존 방식 console.log('안녕'); } };
const obj2 = { sayHi() { // function 키워드 생략 console.log('안녕'); } };
// 계산된 속성명 const key = 'name'; const user3 = { [key]: '철수', // 변수를 속성명으로 사용 [`${key}2`]: '영희' // 표현식도 가능 }; console.log(user3); // { name: '철수', name2: '영희' }12. 자주 하는 실수와 해결법
섹션 제목: “12. 자주 하는 실수와 해결법”실수 1: const 객체 수정
섹션 제목: “실수 1: const 객체 수정”// 잘못된 생각const obj = { a: 1 };// obj = { b: 2 }; // 오류! const는 재할당 불가
// 올바른 방법const obj = { a: 1 };obj.a = 2; // 객체 속성 변경은 가능obj.b = 3; // 새 속성 추가도 가능console.log(obj); // { a: 2, b: 3 }실수 2: 화살표 함수 객체 반환
섹션 제목: “실수 2: 화살표 함수 객체 반환”// 잘못된 코드const getUser = id => { id: id, name: '철수' }; // 중괄호를 코드 블록으로 인식console.log(getUser(1)); // undefined
// 올바른 코드const getUser = id => ({ id: id, name: '철수' }); // 소괄호로 감싸기console.log(getUser(1)); // { id: 1, name: '철수' }실수 3: map에서 return 누락
섹션 제목: “실수 3: map에서 return 누락”// 잘못된 코드const nums = [1, 2, 3];const doubled = nums.map(num => { num * 2 }); // 중괄호 사용 시 return 필요console.log(doubled); // [undefined, undefined, undefined]
// 올바른 코드 1const doubled = nums.map(num => num * 2); // 중괄호 없으면 자동 return
// 올바른 코드 2const doubled = nums.map(num => { return num * 2; }); // return 명시실수 4: forEach로 배열 생성 시도
섹션 제목: “실수 4: forEach로 배열 생성 시도”// 잘못된 코드const nums = [1, 2, 3];const doubled = nums.forEach(num => num * 2); // forEach는 undefined 반환console.log(doubled); // undefined
// 올바른 코드const doubled = nums.map(num => num * 2); // map 사용console.log(doubled); // [2, 4, 6]13. 연습 문제
섹션 제목: “13. 연습 문제”문제 1: 배열 메서드 종합
섹션 제목: “문제 1: 배열 메서드 종합”다음 사용자 배열에서 20세 이상인 사용자의 이름만 추출하세요.
const users = [ { name: '철수', age: 17 }, { name: '영희', age: 22 }, { name: '민수', age: 19 }, { name: '지영', age: 25 }];
// 답: ['영희', '지영']문제 2: 구조 분해와 스프레드
섹션 제목: “문제 2: 구조 분해와 스프레드”user 객체에서 name을 추출하고, 나머지를 rest 변수에 담으세요.
const user = { name: '철수', age: 20, job: '개발자' };
// 답: const { name, ...rest } = user;문제 3: async/await
섹션 제목: “문제 3: async/await”다음 함수를 async/await으로 변환하세요.
function getData() { fetch('https://api.example.com/data') .then(res => res.json()) .then(data => console.log(data));}문제 4: map vs forEach
섹션 제목: “문제 4: map vs forEach”다음 중 어떤 메서드를 사용해야 할까요?
const nums = [1, 2, 3, 4, 5];
// A. 각 숫자에 10을 더한 새 배열이 필요함// B. 각 숫자를 콘솔에 출력만 하고 싶음
// 답: A는 map, B는 forEach15. 핵심 요약
섹션 제목: “15. 핵심 요약”React에서 가장 많이 사용하는 문법 TOP 5
섹션 제목: “React에서 가장 많이 사용하는 문법 TOP 5”- map - 리스트 렌더링
- 구조 분해 할당 - Props 추출
- 화살표 함수 - 이벤트 핸들러
- 스프레드 연산자 - 불변성 유지
- 삼항 연산자 - 조건부 렌더링