📃 features.js
export const formatCurrency = number => {
return number.toLocaleString() + '원'
}
export const formatDate = date => {
const d = new Date(date)
const year = d.getFullYear()
// getMonth()는 0부터 시작하므로 1을 더하고, 10보다 작으면 앞에 0 추가
const month = String(d.getMonth() + 1).padStart(2, '0')
const day = String(d.getDate()).padStart(2, '0')
return `${year}. ${month}. ${day}`
}
// 디바운스 : 연속된 호출을 지연시켜 한번만 실행. 함수(함수, 대시시간)
export const debounce = (func, delay = 300) => {
let timerId
return function (...args) {
if (timerId) clearTimeout(timerId)
timerId = setTimeout(() => {
func.apply(this, args)
}, delay)
}
}
// 쓰로틀 : 일정 시간 동안 한 번만 실행. 함수(함수, 대시시간)
export const throttle = (func, limit = 300) => {
let inThrottle
return function (...args) {
// 일반 함수로 변경
if (!inThrottle) {
func.apply(this, args)
inThrottle = true
setTimeout(() => (inThrottle = false), limit)
}
}
}
🔍 하나하나씩 알아보자!
export const formatDate = date => {
const d = new Date(date)
const year = d.getFullYear()
// getMonth()는 0부터 시작하므로 1을 더하고, 10보다 작으면 앞에 0 추가
const month = String(d.getMonth() + 1).padStart(2, '0')
const day = String(d.getDate()).padStart(2, '0')
return `${year}. ${month}. ${day}`
}
🤔 .padStart가 뭐지?
str.padStart(targetLength [, padString])
- targetLength: 최종 문자열의 길이
- padString: 앞을 채울 문자(기본은 ' ' 공백)
d.getMonth() + 1을 했다. 0월이 없으므로 +1을 해 1월을 의미하고
padStart를 통해 2자리의 길이를 의미하며 한자리 숫자일 경우 01월, 02월을 의미한다.
const day도 마찬가지이다.
return문을 통해서 년, 월, 일을 나타낸다.
🤔 여기서의 func는 무엇을 의미하는 걸까?
// 디바운스 : 연속된 호출을 지연시켜 한번만 실행. 함수(함수, 대시시간)
export const debounce = (func, delay = 300) => {
let timerId
return function (...args) {
if (timerId) clearTimeout(timerId) // 이전 시간을 지우고
timerId = setTimeout(() => {
func.apply(this, args) // 일정 시간 후 func실행
}, delay)
}
}
// => func.apply(this, apply)는 원래 전달된 함수를 원래의 this와 인자로 실행시켜주는 함수이다.
debounce 함수에 인자로 전달되는 실제로 실행하고 싶은 함수를 의미한다.
func는 "내가 나중에 하고 싶은 행동"을 의미한다.
그렇다면 debounce는 그 행동을 일정 시간동안 지연시키는 함수를 만드는 역할을 한다.
const handleInput = (e) => {
console.log('입력 중:', e.target.value)
}
const debouncedInput = debounce(handleInput, 500)
inputElement.addEventListener('input', debouncedInput)
handleInput이 바로 func로 전달이 된다.
debouncedInput은 handle을 0.5초로 지연시키는 함수이므로
사용자가 입력할 때마다 즉시 실행하는 것이 아니라!
입력이 멈춘 후 0,5초 뒤에 실행된다.
📘 그렇다면! 디바운스란 무엇인가?
디바운싱은 연속적으로 발생한 이벤트들 중 마지막 이벤트만 처리하는 기법이다.
일정 시간내 추가 이벤트가발생하면 타이머를 재설정하고, 더 이상 이벤트가 발생하지 않을 때 최종적으로 함수 실행한다.
📘 그렇다면 위에 적힌 스로트링은 무엇인가?
일정 시간 간격으로 함수를 최대 한번 만 실행하도록 제한하는 기법
이벤트를 기다리지않고, 정해진 주기마다 한번씩 함수를 실행한다.
// 쓰로틀 : 일정 시간 동안 한 번만 실행. 함수(함수, 대시시간)
export const throttle = (func, limit = 300) => {
// 지금 실행 여부를 판단하는 inThrottle
let inThrottle
// throttle된 새로운 함수를 반환 (원본은 실행 안 함)
return function (...args) {
// 일반 함수로 변경
if (!inThrottle) {
// 원래 함수 실행
func.apply(this, args)
inThrottle = true
setTimeout(() => (inThrottle = false), limit)
}
}
}
// => inTrottle이 false일때 한정되는것, limit의 시간이 지날 때까지 다시 실행되지 않도록 막는 함수
👉🏻 Header 컴포넌트에 throttle을 사용하는 이유와 동작 원리
import React, { useEffect, useState } from 'react'
...
import { throttle } from '@/utils/features'
const Header = () => {
...
const [isOn, setIsOn] = useState(false)
const location = useLocation()
const addClassOn = () => {
setIsOn(!isOn)
}
useEffect(() => {
setIsOn(false)
}, [location.pathname])
// 2. throttle된 handleResize 동작
// window.resize이벤트가 다량으로 발생해도 hanldResize는 1초에 한번만 실행
const handleResize = throttle(() => {
if (window.innerWidth > 1100) {
setIsOn(false)
}
}, 1000)
// 1. 컴포넌트 마운트
// useEffect는 컴포넌트가 처음나타날때 한 번 실행
// window에 resize이벤트가 나타날땨ㅐ마다 hanleResize를 호출한다.
useEffect(() => {
window.addEventListener('resize', handleResize)
return () => {
window.removeEventListener('resize', handleResize)
}
}, [handleResize])
// [handleResize]를 넣는 이유 = cleanup할 때 정확히 같은 함수를 지우기 위해
...
export default Header
정리
throttle은 resize 같은 과도한 이벤트 호출을 제한해주는 친구!
1초에 한 번만 함수 실행되도록 제한함.
Header.jsx에서는 창 크기가 1100px 이상이면 메뉴를 닫는 용도!
성능 최적화 + 사용자 경험 개선을 동시에!
📘 프록시 서버 설정
프록시 서버란? 클라이언트와 서버 사이에 위치한다.
vite의 서버 프록시 설정은 개발 중에 발생하는 CORS(Cross-Origin-Resouce Sharing)문제를 해결하고 API 요청을 더 효율적으로 관리하기 위해 사용된다.
1. CORS문제 해결
2. API 경로 단순화
3. 환경 간 일관성
📖 프록시 서버 vs vpn 차이
프록시 서버와 vpn은 모두 목적지로 가는 도중에 서버를 통해 트래픽을 라우팅한다. 이를 통해 트래픽 필터링, 정책 시행 및 이와 유사한 이점을 얻는다.
vpn은 항상 사용자와 클라이언트 간의 트래픽을 암호화하며, 클라이언트의 트래픽은 단순히 목적지만 전달한다.
반면 프록시 서버는 서버로 이동하는 트래픽을 암호화하지 않을 수 있으며 클라이언트에 익명성을 제공한다.
프록시 서버란 무엇입니까? - 체크 포인트 소프트웨어
프록시 서버가 무엇인지, 프록시 서버를 통해 트래픽에 악성 콘텐츠가 있는지 검사하고 조직에서 기업 보안을 적용하는 방법에 대해 알아봅니다.
www.checkpoint.com
🐛 실습 중 겪은 문제
코드를 잘 따라 쳤는데 notFound가 뜨는 오류를 발생했다.
아뿔싸.. 단 하나의 오타로 인해 삽질을 했다.
formmatCourrently에서 오타가 발생한 것이다. m을 두번쓰는..
자습시간에 잘 고쳐서 화면 렌더링이 잘되는것을 확인할 수 있었다.
어제본 개념은 오늘다시 봐도 새롭다
아 도라에몽의 암기빵이 필요하다.
'💡 URECA > 🗒️ 스터디 노트' 카테고리의 다른 글
[URECA] Day57 React Shop PROJ - CartPage, ShopPage (0) | 2025.04.21 |
---|---|
[URECA] Day56 React PROJ SHOP (0) | 2025.04.18 |
[URECA] Day54 리액트 lazy, suspense, axios (1) | 2025.04.15 |
[URECA] Day53 React useEffect(), useLocation() (0) | 2025.04.14 |
[URECA] Day52 React Router (1) | 2025.04.11 |