setList((prev) => [...prev, ...additionalItems]);

 

위와 같은 스프레드 연산자가 나열된 구조만 보면 머리가 하얘져서 남겨본다.

 

 

쉽게 생각하자.

스프레드 연산자는 배열, 또는 객체의 요소를 펼치거나 복사할 때 사용한다.

 

 

예시로 두개의 배열을 합쳐보자.

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];

const arrays = [...arr1, ...arr2];
console.log(arrays); 
// [1, 2, 3, 4, 5, 6]

 

이번에는 복사해보자. 말하자면 똑같이 생긴 새로운 배열을 만드는 것이다.

const originalArr = [1, 2, 3];
const copiedArr = [...originalArr];	// 복사

console.log(copiedArr); 
// [1, 2, 3]

 

 

이번에는 객체를 합쳐보자.

const obj1 = { name: 'A', age: 25 };
const obj2 = { job: 'Developer', city: 'Seoul' };
const result = { ...obj1, ...obj2 };

console.log(result); 
// { name: 'A', age: 25, job: 'Developer', city: 'Seoul' }

 

굳이 객체 + 객체 형태가 아니어도, 내용을 직접 넣을 수도 있다.

const originalObj = { name: 'A', age: 25 };
const updatedObj = { ...originalObj, age: 30, city: 'Seoul' }; // 직접 추가

console.log(updatedObj); 
// { name: 'A', age: 30, city: 'Seoul' }

 

 

또한 함수 호출 시, 배열의 각 요소를 함수의 개별 인자로 전달할 때 사용할 수 있다.

const numbers = [1, 2, 3];

function add(a, b, c) {
  return a + b + c;
}

console.log(add(...numbers)); 
// 6

 

 

 

 

다시 맨 처음으로 돌아가서-

스프레드 연산자는 무한스크롤 구현할 때 반드시 필요한데, 침착하게 대응해보자.

const [list, setList] = useState<listItemProps[]>([])
// listItemProps에 지정한 타입형태의 요소로 이루어진 배열. 초기값은 빈 배열

setList((list) => [...list, ...additionalItems]);
// 기존 list에 additionalItems을 더한다.

 

prev는 상태값 list에 들어있던 배열, 또는 객체를 말한다.

말하자면 그냥 상태값을 넣어도 똑같은 식이 된다.

 

 

 

 

 

 

 

어떤 데이터가 있고, 그 안에 {키-값, 키-값} 형태의 객체로 이루어진 배열이 있다.

이 형태의 배열이 여러 개 연속되어 2차원 배열을 이룬다.

 

이를 기반으로, 다음은 가상 키보드를 만드는 과정에서 만든 데이터이다.

 

interface Key {
  code: string;
  label: string;
}

const mainKeys: Key[][] = [
  [
    { code: "`", label: "~" },
    { code: "1", label: "1" },
    { code: "2", label: "2" },
    { code: "3", label: "3" },
    { code: "4", label: "4" },
    { code: "5", label: "5" },
    { code: "6", label: "6" },
    { code: "7", label: "7" },
    { code: "8", label: "8" },
    { code: "9", label: "9" },
    { code: "0", label: "0" },
    { code: "-", label: "-" },
    { code: "=", label: "+" },
    { code: "backspace", label: "←" },
    { code: "Delete", label: "DEL" },
  ],
  [
    { code: "tab", label: "TAB" },
    { code: "q", label: "Q" },
    { code: "w", label: "W" },
    { code: "e", label: "E" },
	
    // 중략...
  ]
]

 

 

code는 키보드 입력을 받는 실제 key의 이름이고, label은 화면 상에 보여질 버튼의 내용이다.

 

알파벳이나 숫자키라면 두 값이 같거나, 단순히 toUpperCase() 등을 통해 통일하여 추적할 수 있다.

그러나 그 값이 서로 규칙성이 없는 경우 (예: Delete - DEL) 는 추적할 수 없다.

 

이런 경우 입력된 code 값만을 통해 짝지어진 label의 값을 추적하는 방법을 알아보자.

 

 

Map 객체 활용하기

const codeToLabelMap = new Map<string, string>();
	mainKeys.forEach(row => {
    	row.forEach(elem => {
        	codeToLabelMap.set(elem.code, elem.label);
        })
      })
      
function findLabelByCode(code: string): string {
	return codeToLabelMap.get(code)
}

const exampleCode = "`" // 찾고자 하는 코드값
const exampleLabel = findLabelByCode(exampleCode) // 만든 함수에 찾고자 하는 코드값 입력
console.log(exampleLabel) // "~"

 

 

Map은 javascript 내장 자료구조이다.

키-값 쌍을 객체 형태로 저장하게 된다.

 

new Map<string, string>( ) 에서 첫번째 string은 code가 들어갈 자리이고, 두번째 string은 label이 들어갈 자리이다.

 

 

mainKeys 배열을 순회한다.

가장 바깥쪽 배열인 row를 forEach로 순회하고, 그 안에 있는 요소인 각 객체 { code: "`", label: "~" } 조각(element)들을 순회한다.

위에서 만들어둔 codeToLabelMap 객체의 code, label에 들어갈 값을 각각 지정한다.

 

이제 code, label 을 담은 새로운 객체가 완성되었으니, findLabelByCode 함수를 작성해 원하는 값에 접근한다.

입력될 값 code는 문자열이므로 (code: string) 이라고 작성하고, 출력될 값 또한 문자열이므로 그 바깥에 선언해준다.

 

 

 

 

 

'개념 정리' 카테고리의 다른 글

스프레드 연산자와 배열 합치기  (0) 2024.11.12
javascript - 유사배열객체, Array.from( )  (0) 2024.10.28
javascript - reduce()  (1) 2024.10.28
새로운 리액트 프로젝트 생성하기  (0) 2024.10.16
HTTP와 HTTPS  (0) 2024.02.05

 

 

유사배열객체(Array-like Object)

배열처럼 length 속성을 가지지만 배열이 아닌 객체를 말한다.

배열이 아니기 때문에 map, filter, reduce 등 배열 고유 메서드를 사용할 수 없다.

 

const arrayLike = {
  0: "apple",
  1: "banana",
  2: "peach",
  length: 3	// length를 반드시 입력
};

console.log(arrayLike[0]); // "apple"
console.log(arrayLike.length); // 3

 

 

 

 

 

Array.from( )

 

기본형

Array.from(iterable, mapFunction, thisArg)
  • iterable: 배열로 변환할 반복 가능한 객체( 문자열, Set, Map 등) 또는 유사 배열 객체.
  • mapFunction (optional): 배열의 각 요소에 적용할 함수. Array.from의 결과 배열을 생성하면서 동시에 매핑을 할 수 있다.
    • 첫번째 인자: 현재 요소의 값. 유사 배열 객체의 경우 보통 undefined
    • 두번째 인자: 현재 요소의 index
  • thisArg (optional): mapFunction 실행 시 this로 사용될 값.

 

예제

// 문자열을 쪼개서 배열로 바꾸기
const str = "Hello";
const arr = Array.from(str);
console.log(arr); // ['H', 'e', 'l', 'l', 'o']

 

// 유사배열객체를 배열로 바꾸기
const arrayLike = { 0: "a", 1: "b", 2: "c", length: 3 };
const arr = Array.from(arrayLike);
console.log(arr); // ['a', 'b', 'c']

 

// 각 요소 순회하며 함수 매핑하기
const arr = Array.from([1, 2, 3], x => x * 2);
console.log(arr); // [2, 4, 6]

 

// 길이가 5인 배열 생성하기
const arr = Array.from({ length: 5 }, (_, index) => index);
console.log(arr); // [0, 1, 2, 3, 4]

 

 

 

 

Array.from({ length: count }

위 코드는 "count라는 변수만큼의 length를 가진 배열을 생성한다"는 뜻이다.

 

 

 

 

 

 

 

 

배열의 각 요소에 대해 주어진 함수(callback)을 실행하여 단일한 결과값을 만들어낸다.

배열의 총합, 최대 or 최소값, 평균, 또는 배열을 객체로 변환할 때 유용하다.

 

 

기본형

array.reduce((accumulator) => { return.. }, initialValue);

 

  • 첫번째 매개변수: 배열의 각 요소에 대해 실행할 콜백함수
    • accumulator (누적값)
    • currentValue (현재 요소 값) : accumulator가 0이라면 1, 아닌 경우 0부터 시작
    • currentIndex (현재 인덱스)
    • array (배열 전체)
  • 두번째 매개변수: initialValue (선택 사항): accumulator의 초기값. 생략하면 첫 번째 요소가 초기값으로 설정된다.

 

 

예제

numbers 배열에 있는 모든 요소의 합을 구하는 경우, 다양한 방식이 있다.

// 메소드 없이 for문으로 순회
const numbers = [1, 2, 3, 4]
let total = 0
for (let i = 0, i <= numbers.length, i++) {
	total += numbers[i]
}
// forEach 메소드 활용
const numbers = [1, 2, 3, 4]
let total = 0
numbers.forEach((number) => {
	total = total + number
})

 

// reduce 사용한 경우
const numbers = [1, 2, 3, 4]

const total = numbers.reduce((accumulator, currentValue) => {
	return accumulator + currentValue
}, 0) // 0은 accumulator의 초기값

 

 

 

최대값을 구해보자.

// 최대값 구하기
const numbers = [8, 10, 24, 7]

numbers.reduce((accumulator, currentValue) => {
	if (accumulator < currentValue){
    	return currentValue	// accumulator의 값을 currentValue로 업데이트
    }
    else {
    	return accumulator
    }
}) //초기값을 지정하지 않았으므로 [0]번째부터 시작

 

 

이번에는 배열 내 객체 요소의 합을 구해보자.

const account = [
    {name: "A",
     cost: 100,
    },
    
    {name: "B",
     cost: 600,
    },
    
    {name: "C",
     cost: 20,
    },
]


account.reduce((accumulator, elem) => {
	return accumulator + account.cost
}, 0)

 

 

 

 

 

 

 

 

 

 

 

매번 프로젝트를 생성할 때마다 명령어를 잊어버려서 작성해둔다.

 

cd ~/Desktop

npx create-react-app new-project --template typescript

cd new-project

 

 

폴더 삭제

rm -rf project-name

 

 

Git 리포지토리 추가

git remote add origin https://github.com/<your-username>/my-new-repo.git

 

 

yarn 설치

brew install yarn
yarn --version

 

 

HTTP

  • 데이터가 평문으로 전송된다. 즉, 작성 및 제출한 정보 및 경로를 가로챌 수 있다.
  • 암호화되지 않은 통신을 사용하기 떄문에 비밀번호, 개인정보 등의 보안이 취약하다.
  • 통신 상태를 확인하지 않으므로 신뢰할 수 있는 서버인지 알 수 없다.
  • 80번 포트를 사용한다.

 

HTTPS

  • 데이터가 암호화되어 전송되어 보다 안전하다. (Encryption)

    - TLS(Transport Layer Security, SSL(Secure Sockets Layer) 프로토콜

  • TLS, SSL 인증서를 통해 웹 서버의 신뢰성을 증명할 수 있고, 클라이언트와 서버 간 안전한 통신을 할 수 있게 한다.
  • 443번 포트를 사용한다.

 

 

 

 


 

 

 

HTTPS를 적용하는 방법

 

  • TLS/SSL 인증서 획득 : CA(Certificate Authority)에서 제공
  • 웹서버에 TLS/SSL 적용 : 해당 인증서를 설치한 뒤 서버 설정을 하여 HTTPS 프로토콜을 활성화 한다.
  • HTTP Redirection 설정 : 모든 HTTP 요청이 HTTPS로 전환되게 한다.
  • 보안 헤더 추가 : HSTS(Strict-Transport-Security) 헤더를 추가해 브라우저가 웹 사이트를 항상 HTTPS로 연결하도록 한다.

 

 

Class로 모듈화 하기

import { makeDOMwithProperties } from '/directory/test.js'

	const noticeDOM = makeDOMwithProperties ('div', {
        innerHTML : '내용 없음',
        className : 'product-list-con'
    });

 

export const makeDOMwithProperties = (domType, propertyMap) => {
    //domType : div, a , li...
    //propertyMap : {"className" : "product-card", "alt"...}

    //Object.keys() 란? --- 키 값을 배열로 넘김
    //예시) Object.keys(propertyMap) ---> ["className", "alt"] 
    
    const dom = document.createElement(domType)
    Object.keys(propertyMap).forEach((key) => {
        dom[key] = propertyMap[key];
    });

    return dom;
}

export const appendChildrenList = (target, childrenList) => {
    if (!Array.isArray(childrenList)) return; //early return이라고 한다. if/else 구문은 길어지기 때문에, 아닌 경우만 먼저 솎아낸다.

    childrenList.forEach((child) => {
        target.appendChild(child); //childrenList의 배열에 들어있는 children을 붙임
    })
};

 

 

 

 


 

 

 

브라우저 저장소

 

LocalStorage

  • 브라우저를 닫아도 데이터가 유지된다.
  • 동일한 도메인에서만 접근할 수 있다. (Same-Orgin Policy)
  • 간단한 인터페이스로 사용하기 쉽다.

 

  • 브라우저 당 약 5MB 정도의 저장 공간만 가질 수 있다.
  • 문자열만 저장 가능하며, 객체나 배열 등의 데이터 구조를 저장할 수 없다.

 

 

SessionStorage

 

  • 임시로 데이터를 저장하여 같은 탭이나 창 간 데이터를 공유할 수 있다. 
  • 동일한 도메인에서만 접근할 수 있다. (Same-Orgin Policy)

 

  • 브라우저를 닫으면 (세션을 종료하면) 데이터가 삭제된다.

 

 

IndexedDB

 

  • 객체 지향형 데이터 베이스로 구조화된 데이터를 저장할 수 있다.
  • 비동기적(Asynchronized)으로 데이터를 읽고 쓸 수 있기 때문에 대량의 데이터를 처리할 수 있다.
  • 동일한 도메인에서만 접근할 수 있다. (Same-Orgin Policy)

 

  • 사용자에게 데이터 관리 책임이 있다.
  • 사용하기 복잡하다.
  • 구형 브라우저에 지원되지 않을 수 있다.

'개념 정리' 카테고리의 다른 글

새로운 리액트 프로젝트 생성하기  (0) 2024.10.16
HTTP와 HTTPS  (0) 2024.02.05
HTML의 noreferrer, nopener, nofollow  (0) 2024.01.21
Flex와 Grid  (0) 2024.01.21
반응형 작업과 mediaquery 최소화  (0) 2024.01.21

 

 

noreferrer, nopener, nofollow는 웹 보안 및 사용자의 개인정보보호 강화를 위해 사용되는 속성이다.

 

 

noreferrer

하이퍼링크를 통해 이동할 때, 현재 페이지의 referrer 정보를 전달하지 않도록 한다.

현재 페이지의 주소가 외부 사이트로 전달되는 것을 방지한다.

 

referrer 정보란?

이전 페이지의 URI를 나타내는 정보. 어떤 사이트에서 유입되었는지 분석하여 사용자의 트래픽 추적이 가능하다.

 

 

 

nopener

하이퍼링크로 열린 새 창이 자신을 열지 않도록 하는 속성.

새 창이 열릴 때, 열린 창이 부모 창(이전 창) 에 대한 제어 권한을 갖지 못하게 한다. 

+ CSRF 공격을 막을 수 있다.

 

CSRF 공격이란?

Cross-Site Request Forgery의 약자.

사용자가 의도하지 않은 요청을 악의적인 웹 사이트를 통해 다른 웹 사이트에 전송한다. 

 

<script>
	window.opener = null;
</script>

 

 

 

nofollow

rel 속성에 사용되며, 검색 엔진이 해당 링크를 따라가지 않도록 지시한다.

검색 엔진 최적화(SEO)에서 해당 외부 사이트로의 링크가 현재 사이트의 검색 엔진 순위에 영향을 주지 못하도록 한다.

신뢰할 수 없는 사이트로 이동할 때, 검색 엔진이 해당 사이트로의 링크가 전달되는 것을 방지한다.

 

SEO란?

Search Engine Optimization의 약자. 웹 사이트가 검색 엔진에서 노출되기 용이하게 최적화하는 프로세스.

 

 

 

 

 

그 외 보안 이슈에 대한 처리

최신 브라우저 지원

HTTPS 사용

정기적인 보안 업데이트 및 보안 취약점 최소화 등

'개념 정리' 카테고리의 다른 글

HTTP와 HTTPS  (0) 2024.02.05
Javascript Class를 활용해 모듈화 하기 / 브라우저 저장소  (0) 2024.02.05
Flex와 Grid  (0) 2024.01.21
반응형 작업과 mediaquery 최소화  (0) 2024.01.21
CSS 애니메이션 최적화  (0) 2024.01.21

+ Recent posts