| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
- 파이썬문법
- 카카오클라우드
- Kaggle
- 데이터분석
- 개발자교육
- 스나이퍼팩토리
- 한국생산성본부
- 오늘의로하
- olist
- 이커머스데이터분석
- 하늘도시맛집
- AIaaS
- 클라우드개발자
- 카카오엔터프라이즈
- 판교생활
- 포트폴리오
- 영종도카페
- 인턴생활
- 태블로
- wecookieyou
- 꾸석지돌판한우
- 데이터분석포트폴리오
- 클라우드엔지니어
- 판교타코익스프레스
- 하루기록
- 부트캠프
- tableau
- AIaaS마스터클래스2기
- 하늘도시속눈썹
- sql
- Today
- Total
Alroha
[스나이퍼팩토리] 카카오클라우드 - 클라우드 개발자 교육 3주차(1) 본문
벌써 교육 시작한 지 2주를 넘어 3주 차가 시작됐다.
강의 듣고 실습하면 하루 뚝딱 넘어가니까 시간 가는 줄 모르고 하루하루 보내고 있다.
이러다 얼레벌레 부트캠프 끝나지 않게 미리미리 정리하는 습관 잘 들이자!!💪🏻💪🏻
11일차-REACT HOOK 및 심화 개념
1. Hook 개념
Hook : 함수형 컴포넌트에서 상태와 라이프사이클을 관리할 수 있게 해주는 기능.
기존 클래스형 컴포넌트에서만 가능했던 기능(state, lifecycle 등)을 함수형에서도 다룰 수 있게 해준다.
주요 Hook 종류:
- useState : 상태 관리
- useEffect : 사이드 이펙트(렌더링 이후 실행) 관리
- useMemo : 값 메모이제이션
- useCallback : 함수 메모이제이션
- useRef : DOM 직접 접근, 값 유지
- useReducer : 복잡한 state 관리
- useContext : 전역 상태 관리
2. useState
- 여러 개 사용 가능
- e.target.value를 통해 실시간 데이터 입력 확인 가능
- 상태 변경 시 자동으로 리렌더링 발생
import { useState } from "react";
function InputExample() {
const [name, setName] = useState("");
const onChangeName = (e) => {
setName(e.target.value);
};
return (
<div>
<input value={name} onChange={onChangeName} />
<p>입력값: {name}</p>
</div>
);
}
3. useEffect
컴포넌트가 렌더링 될 때마다 특정 작업을 수행하도록 설정 가능.
렌더링이 될때마다 콘솔창에 렌더링이 완료되었다는 문구를 띄울 수 있음.
맨 처음 렌더링될때만 실행하고 업데이트될 때는 실행하지 않으려면 함수의 두번째 파라미터로 비어있는 배열을 넣어주면 됨.
- 마운트 될 때 한 번만 실행
- useEffect(() => { console.log("마운트 될 때만 실행"); }, []);
- 특정 값이 업데이트 될 때 실행(두번째 파라미터 배열에 무엇을 넣는지에 따라 실행 조건이 달라진다.)
- useEffect(() => { console.log("name이 바뀔 때 실행"); }, [name]);


4. (공통과제1)useMemo
메모이제이션된 값을 반환.
불필요한 연산 최소화 → 성능 최적화메모이제이션이란 기존에 수행한 연산의 결과를 어딘가에 저장해두고 동일한 입력이 들어오면 재활용하는 프로그래밍 기법으로 중복 연산을 피할 수 있기 때문에 메모리를 조금 더 쓰더라도 애플리케이션의 성능을 최적화시킨다. 의존성 배열에 들어있는 변수가 변했을 경우에만 새로 함수를 호출하여 결과값을 반환한다.
이를 통해서 숫자를 등록할때마다 렌더링 과정에서 특정 값이 바뀌었을때만 연산을 실행하고, 원하는 값이 바뀌지 않았다면 이전에 연산했던 결과를 다시 사용할 수 있다.
import { useState, useMemo } from "react";
const getAvg = (numbers) => {
console.log("평균값 계산 중..");
if (numbers.length === 0) return 0;
return numbers.reduce((a, b) => a + b) / numbers.length;
};
const Average = () => {
const [list, setList] = useState([]);
const [numbers, setNumbers] = useState("");
const onChange = (e) => setNumbers(e.target.value);
const onInsert = () => {
setList(list.concat(parseInt(numbers)));
setNumbers("");
};
const avg = useMemo(() => getAvg(list), [list]); // list 변경시에만 재계산
return (
<div>
<input value={numbers} onChange={onChange} />
<button onClick={onInsert}>등록</button>
<ul>
{list.map((value, index) => (
<li key={index}>{value}</li>
))}
</ul>
<b>avg: {avg}</b>
</div>
);
};


5. React.memo
컴포넌트를 메모이제이션하여 props가 바뀌지 않으면 리렌더링을 방지
const Child = React.memo(({ value }) => {
console.log("Child 렌더링");
return <div>{value}</div>;
});
6. useRef
- DOM 요소 직접 접근 (document.querySelector 대신)
- 컴포넌트가 리렌더링 되어도 값이 유지됨
- state와 달리 변경해도 리렌더링이 일어나지 않음
🔎 변수, state, useRef 비교
구분 리렌더링 발생 값 유지 주요 활용
| 변수 | ❌ | ❌ | 단순 계산용 |
| state | ✅ | ✅ | UI 업데이트 |
| useRef | ❌ | ✅ | DOM 접근, 값 캐싱 |
import { useState, useRef } from "react";
function RefExample() {
const [count, setCount] = useState(0);
const ref = useRef(0);
const increase = () => {
setCount(count + 1); // 리렌더링 발생
ref.current += 1; // 값은 바뀌지만 리렌더링 X
console.log("ref 값:", ref.current);
};
return (
<div>
<p>state count: {count}</p>
<p>ref count: {ref.current}</p>
<button onClick={increase}>증가</button>
</div>
);
}
7. useReducer
복잡한 상태 관리에 유리.
(Redux의 축소판 느낌)
import { useReducer } from "react";
function reducer(state, action) {
switch (action.type) {
case "INCREMENT":
return { count: state.count + 1 };
case "DECREMENT":
return { count: state.count - 1 };
default:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
<p>{state.count}</p>
<button onClick={() => dispatch({ type: "INCREMENT" })}>+</button>
<button onClick={() => dispatch({ type: "DECREMENT" })}>-</button>
</div>
);
}
8. Context API & useContext
props drilling 문제 해결 (깊은 컴포넌트까지 데이터 전달)
import { createContext, useContext } from "react";
const ThemeContext = createContext("light");
function Child() {
const theme = useContext(ThemeContext);
return <p>현재 테마: {theme}</p>;
}
function App() {
return (
<ThemeContext.Provider value="dark">
<Child />
</ThemeContext.Provider>
);
}
9. (공통과제2)Custom Hook
반복되는 로직을 함수로 추출해서 재사용 가능한 Hook을 만드는 것.
use 접두사로 이름을 지어야 함.
useFetch 예제
import { useState, useEffect } from "react";
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchData = async () => {
setLoading(true);
const res = await fetch(url);
const json = await res.json();
setData(json);
setLoading(false);
};
fetchData();
}, [url]);
return { data, loading };
}
export default useFetch;
사용:
function PostList() {
const { data, loading } = useFetch("https://jsonplaceholder.typicode.com/posts");
if (loading) return <p>로딩중...</p>;
return (
<ul>
{data.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
11일차-REACT + TypeScript기초
1. 이벤트 핸들러(Event Handler)
리액트에서 UI는 상태(state)와 밀접하게 연결된다. 사용자가 버튼을 클릭하거나 입력값을 변경하면 이벤트 핸들러가 호출되고, 이는 상태 업데이트로 이어진다. 상태가 변경되면 리액트는 이를 기반으로 UI를 다시 렌더링한다.
리액트에서 이벤트를 다루는 방식은 일반 HTML 과 유사하지만, 몇 가지 차이점을 가진다.
| HTML 이벤트 | React 이벤트 | |
| 네이밍 | onclick, onchange (소문자) | onClick, onChange (카멜 케이스) |
| 전달 방식 | 문자열로 핸들러 지정 가능 | 반드시 함수 참조를 전달해야 함 |
| 기본 동작 막기 | return false | event.preventDefault() 호출 |
예시:
function MyButton() {
const handleClick = (e) => {
e.preventDefault();
alert("버튼 클릭됨!");
};
return <button onClick={handleClick}>Click Me</button>;
}
👉 즉, 리액트의 이벤트는 JSX 속성에 함수 참조를 전달하는 방식으로 동작한다.
2. React의 상태 관리 흐름
리액트 애플리케이션은 상태(state) → UI → 이벤트 → 상태 업데이트라는 사이클로 동작.
이벤트 핸들러는 UI에서 발생한 변화를 다시 상태에 반영하는 매개체 역할을 한다.
3. useState와 useEffect
이벤트 핸들러는 결국 상태 관리를 통해 UI 변화를 만든다. 이때 사용하는 대표적인 훅이 useState이다.
- useState: 여러 개 사용 가능, 입력값은 e.target.value를 활용해 실시간으로 관리한다.
- useEffect: 렌더링이 발생할 때 특정 작업을 수행할 수 있도록 해준다.
useEffect(() => {
console.log("마운트 될 때만 실행");
}, []);
두 번째 파라미터에 들어가는 배열([])에 따라 실행 조건이 달라지며, 특정 값이 업데이트될 때만 실행되도록 설정할 수도 있다.
4. 성능 최적화를 위한 훅
상태가 많아지고 연산이 복잡해지면, 불필요한 연산을 줄이는 최적화가 필요하다.
- useMemo: 특정 값이 바뀌었을 때만 연산 수행 → 불필요한 계산 방지
- React.memo: props가 변하지 않으면 컴포넌트 리렌더링을 막음
- useRef: DOM에 직접 접근하거나 렌더링과 무관한 값을 저장할 때 사용
구분 특징 렌더링 영향
| 변수 | 함수 실행 시마다 초기화됨 | 항상 초기화 |
| state | 상태 변경 시 컴포넌트 리렌더링 | 렌더링 O |
| useRef | 렌더링과 무관, 값 유지 | 렌더링 X |
5. useReducer와 Context API
useState로 관리하기 어려운 복잡한 상태 로직은 useReducer로 분리할 수 있다.
또한, props를 여러 단계로 내려주는 props drilling 문제는 Context API로 해결한다.
전역적인 데이터(로그인 정보, 테마, 언어 등)를 Context에 담으면 하위 컴포넌트에서 쉽게 접근할 수 있다.
6. Custom Hook
프로젝트가 커지면 반복되는 로직이 많아진다. 이때 공통 로직을 추출해 Custom Hook으로 관리한다.
function useFetch(url) {
const [data, setData] = useState(null);
useEffect(() => {
fetch(url).then(res => res.json()).then(setData);
}, [url]);
return data;
}
이렇게 만든 useFetch 훅을 여러 컴포넌트에서 재사용할 수 있다.
7. 컴포넌트 재사용성: 합성과 상속
리액트는 컴포넌트를 작게 쪼개고 재사용할 수 있는 구조를 제공한다. 이때 중요한 개념이 합성과 상속이다.
- 상속: 기존 클래스를 확장하는 방식이지만, 리액트에서는 잘 사용하지 않는다.
- 합성: 여러 개의 컴포넌트를 조합해서 새로운 UI를 만드는 방식 → 추천.
리액트는 "상속보다 합성"을 지향하며, 이는 컴포넌트의 독립성과 유연성을 높인다.
8. Redux: 전역 상태 관리의 필요성
리액트의 로컬 상태 관리(useState, useReducer)만으로는 대규모 애플리케이션에 한계가 있다. 대표적인 문제가 props drilling과 전역 상태 공유이다.
이를 해결하는 가장 대표적인 상태 관리 라이브러리가 Redux다.
| 액션(Action) | 상태 변화의 의도를 담은 객체 |
| 리듀서(Reducer) | 액션을 받아 새로운 상태를 반환하는 함수 |
| 스토어(Store) | 애플리케이션의 전역 상태 보관소, 단 하나만 존재 |
| 디스패치(Dispatch) | 액션을 발생시키는 함수 |
리덕스를 사용하면 상태 업데이트 로직을 분리할 수 있고, 상태 변경을 예측 가능하게 관리할 수 있다. 특히 서버와 연동되는 비동기 로직까지 제어할 수 있어 규모가 큰 프로젝트에서 필수적이다.
타입스크립트 기초
최근 프론트엔드에서 강조되는 또 다른 키워드는 타입 안정성이다.
자바스크립트는 동적 언어라서 오류를 실행 중에야 알 수 있지만, 타입스크립트는 정적 타입 검사를 제공해 컴파일 단계에서 오류를 잡아낸다.
주요 특징
- 강력한 타입 시스템 (boolean, number, string, null, undefined)
- 배열과 튜플 지원 (동일 타입 집합 vs 여러 타입 혼합)
- any, unknown, union, intersection, literal 타입
- enum: 관련된 상수 집합 정의
- 함수 타입 지정 (매개변수, 반환 값 타입)
- 인터페이스: 객체 구조 정의
- 클래스와 상속: extends 키워드, 접근 제어자, 추상 클래스 지원
- 제네릭: 타입 변수를 활용한 재사용 가능한 컴포넌트 생성
- 네임스페이스: 이름 충돌 방지
예시
let isDone: boolean = false;
let list: number[] = [1, 2, 3];
let tuple: [string, number] = ["age", 25];
enum Color { Red, Green, Blue }
타입스크립트는 리액트와 함께 사용될 때 특히 강력하다. 컴포넌트 props에 타입을 지정하면, 잘못된 데이터 전달을 컴파일 단계에서 잡아낼 수 있기 때문이다.
이렇게 오늘까지 프론트엔드 강의가 호다다다닥 끝나버렸다..🏃🏻♂️🏃🏻🏃🏻♀️
너무 어려운것..💦💦💦💦
본 후기는 [카카오엔터프라이즈x스나이퍼팩토리] 카카오클라우드로 배우는 AIaaS 마스터 클래스 2기(B-log) 리뷰로 작성 되었습니다.
'IT > Kakao cloud 부트캠프' 카테고리의 다른 글
| [스나이퍼팩토리] 카카오클라우드 - 클라우드 개발자 교육 5주차 (0) | 2025.09.08 |
|---|---|
| [스나이퍼팩토리] 카카오클라우드 - 클라우드 개발자 교육 4주차 (11) | 2025.09.01 |
| [스나이퍼팩토리] 카카오클라우드 - 클라우드 개발자 교육 3주차(2) (1) | 2025.08.26 |
| [스나이퍼팩토리] 카카오클라우드 - 클라우드 개발자 교육 2주차 (22) | 2025.08.14 |
| [스나이퍼팩토리] 카카오클라우드 - 클라우드 개발자 교육 1주차 (21) | 2025.08.08 |