프론트엔드에서는 변수를 다루를 때 var, let, const를 사용해서 선언합니다. 각각이 어떤 차이를 가지고 있는지에 대해서 한번 다루어 보고자 합니다. 

Var 

스코프 

var는 함수 스코프를 가집니다. 그렇기 때문에 변수가 선언된 함수 내에서만 유효합니다. 블록 스코프를 지원하지 않기 때문에 if, for등의 블록안에서 선언해도 블록 외부에서 접근이 가능합니다. 

호이스팅

var로 선언된 변수는 호이스팅되어 변수 선언이 코드의 최상단으로 끌어 올려집니다. 하지만 초기화는 호이스팅되지 않으므로 선언 전에 접근하면 undefined를 반환합니다. 

function testVar() {
  if (true) {
    var x = 10; // 블록 내부에서 선언
  }
  console.log(x); // 블록 외부에서도 접근 가능
}
testVar(); // 출력: 10

Let 

스코프

let은 블록스코프를 가집니다. 블록내에서만 유효하며 블록 외부에서는 접근할 수 없습니다. 

 

호이스팅

let으로 선언된 변수도 호이스팅 되지만 TDZ(Temporal Dead Zone)때문에 초기화 전에 접근하려 하면 ReferenceError가 발생합니다.

function testLet() {
  if (true) {
    let y = 20; // 블록 내부에서 선언
    console.log(y); // 출력: 20
  }
  console.log(y); // ReferenceError: y is not defined
}
testLet();

 

const 

스코프 

const도 let과 마찬가지로 블록 스코프를 가집니다. 

 

상수 

const로 선언된 변수는 재할당이 불가능합니다. 하지만 참조형 데이터(예: 배열, 객체)의 경우, 내부 값은 변경할 수 있습니다. 

 

호이스팅 

const도 호이스팅되지만 let과  마찬가지로 TDZ때문에 초기화 이전에 접근하면 referenceError가 발생합니다.

const z = 30;
z = 40; // TypeError: Assignment to constant variable.

const obj = { name: "Alice" };
obj.name = "Bob"; // 객체 내부의 속성은 변경 가능
console.log(obj.name); // 출력: Bob

 

결론 

const를 기본으로 사용하는 것이 좋습니다. 변수에 재할당이 필요하지 않다면 const로 선언해 안정성을 높이는 것이 좋습니다. 

let은 재할당이 필요한 경우에만 사용하는 것이 좋습니다. 

var는 사용하지 않는 것이 권장됩니다. 함수 스코프와 호이스팅으로 인해 예기치 않은 동작이 발생할 수 있습니다.

 


++ TDZ에 대해서 

TDZ(temporal Dead Zone)은 자바스크립트에서 let과 const로 선언된 변수를 초기화 전에 접근하려고 할 때 발생하는 특별한 구역을 의미합니다. TDZ는 변수 선언이 호이스팅되지만, 초기화가 되지 않은 상태에서 접근을 시도하면 에러를 발생시키는 구역입니다. 

function testTDZ() {
  console.log(a); // ReferenceError: Cannot access 'a' before initialization
  let a = 10; // 변수 'a'의 초기화
}

testTDZ();

let a=10;으로 a변수를 선언했지만 선언만 호이스팅되고 초기화는 나중에 이루어지기 때문에, console.log(a)에서 초기화 전인 TDZ구간에서 a에 접근하려 하면 ReferenceError가 발생합니다. 

 

var의 경우에는 TDZ의 영향을 받지 않습니다. var는 함수 스코프로 동작하며, 선언은 호이스팅되지만 TDZ가 적용되지 않기 때문에 초기화 전에 접근해도 undefined로 값이 반환됩니다. 

function testVar() {
  console.log(c); // 출력: undefined
  var c = 30; // 변수 c의 초기화
}

testVar();

 

그렇다면 TDZ는 왜 필요한걸까요? 

TDZ는 예기치 않은 오류를 방지하고 코드의 안정성을 높이는 데 중요한 역할을 합니다. let과 const를 사용함으로써 변수가 초기화 되기 전에 접근하는 실수를 줄이기 위해Javascript엔진이 이를 강제로 막아줍니다. 

 

React에서 컴포넌트를 만드는 방식은 함수형 컴포넌트클래스형 컴포넌트 두 가지로 나눌 수 있습니다. 최근 React에서는 함수형 컴포넌트와 Hooks를 주로 사용하지만, 클래스형 컴포넌트 역시 여전히 많은 프로젝트에서 사용됩니다. 이번 블로그 글에서는 함수형 컴포넌트와 클래스형 컴포넌트를 비교하며 각 방식의 차이점, 장단점, 그리고 사용 사례에 대해 살펴보겠습니다.

 

1. 함수형 컴포넌트란?

함수형 컴포넌트는 간단하게 함수로 정의되며, JSX를 반환하는 구조입니다. 상태를 관리하거나 생명주기 메서드를 사용하기 위해 React의 Hooks를 활용할 수 있습니다. 최신 React 애플리케이션에서는 주로 함수형 컴포넌트가 사용되고 있습니다.

import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

export default Counter;

함수형 컴포넌트의 주요 특징

  • 간결함: 함수형 컴포넌트는 코드가 간단하고 선언적입니다.
  • Hooks 사용: useState, useEffect 등과 같은 Hooks를 사용해 상태 관리 및 생명주기와 유사한 기능을 처리할 수 있습니다.
  • 가벼움: 클래스형 컴포넌트보다 메모리 측면에서 더 효율적입니다.

2. 클래스형 컴포넌트란?

클래스형 컴포넌트는 class 키워드를 사용해 정의되며, state와 생명주기 메서드(componentDidMount, componentDidUpdate 등)를 통해 컴포넌트의 상태와 행동을 관리합니다. 함수형 컴포넌트보다 문법이 복잡하지만, React의 초기부터 사용된 방식입니다.

import React, { Component } from 'react';

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }

  increment = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return (
      <div>
        <h1>Count: {this.state.count}</h1>
        <button onClick={this.increment}>Increment</button>
      </div>
    );
  }
}

export default Counter;

클래스형 컴포넌트의 주요 특징

  • 클래스 사용: ES6 class 문법을 사용하여 정의됩니다.
  • 생명주기 메서드: 컴포넌트가 마운트되거나 업데이트될 때 실행되는 생명주기 메서드를 제공합니다.
  • this 사용: 클래스 컴포넌트에서는 this 키워드를 사용해 상태나 메서드에 접근해야 합니다.

3. 함수형 컴포넌트와 클래스형 컴포넌트 비교

항목함수형 컴포넌트클래스형 컴포넌트

정의 방식 함수로 정의 class로 정의
상태 관리 useState와 같은 Hooks를 사용 this.state와 setState() 사용
생명주기 관리 useEffect를 통해 생명주기 관리 가능 componentDidMount, componentDidUpdate 등 생명주기 메서드 사용
코드 구조 간결하고 선언적 상대적으로 복잡하고 명령적
this 사용 필요 없음 this로 상태 및 메서드에 접근
Hooks 지원 완벽히 지원 (useState, useEffect 등) Hooks 사용 불가

1) 코드의 간결성

함수형 컴포넌트는 함수로 정의되고 Hooks를 통해 상태나 생명주기 메서드를 쉽게 사용할 수 있어 코드가 더 간결합니다. 클래스형 컴포넌트는 constructor, this 키워드를 사용해야 해서 더 복잡한 구조를 가집니다.

2) 생명주기 관리

클래스형 컴포넌트는 생명주기 메서드를 사용해 컴포넌트의 마운트, 업데이트, 언마운트 등의 시점에 특정 동작을 정의할 수 있습니다. 함수형 컴포넌트에서는 useEffect 훅을 사용해 이와 같은 기능을 구현할 수 있습니다.

 

클래스형 컴포넌트의 생명주기 메서드 예시

class MyComponent extends React.Component {
  componentDidMount() {
    console.log('Component mounted');
  }

  componentDidUpdate(prevProps, prevState) {
    console.log('Component updated');
  }

  render() {
    return <div>My Component</div>;
  }
}

 

함수형 컴포넌트에서 useEffect를 이용한 생명주기 관리

import React, { useEffect } from 'react';

const MyComponent = () => {
  useEffect(() => {
    console.log('Component mounted or updated');
  });

  return <div>My Component</div>;
};

3) Hooks의 등장

Hooks의 도입으로 함수형 컴포넌트가 더욱 강력해졌습니다. 이전에는 클래스형 컴포넌트에서만 상태 관리 및 생명주기 메서드를 사용할 수 있었지만, Hooks 덕분에 함수형 컴포넌트에서도 이를 사용할 수 있게 되어 함수형 컴포넌트가 더 선호되고 있습니다.

 

4. 결론: 언제 어떤 컴포넌트를 사용해야 할까?

클래스형 컴포넌트는 기존 코드나 레거시 프로젝트에서 많이 사용되며, 아직도 유지보수가 필요할 때 유용할 수 있습니다. 하지만 새롭게 프로젝트를 시작한다면, 함수형 컴포넌트와 Hooks를 사용하는 것이 더 효율적입니다.

  • 레거시 코드: 기존에 클래스형 컴포넌트를 많이 사용해온 프로젝트라면 유지보수 차원에서 클래스를 계속 사용해야 할 수도 있습니다.
  • 새 프로젝트: 최신 기능을 활용하고 더 간결한 코드를 작성하고 싶다면 함수형 컴포넌트와 Hooks를 사용하는 것이 좋습니다.

React의 방향성은 함수형 컴포넌트에 무게를 두고 발전하고 있으므로, 앞으로는 함수형 컴포넌트가 기본 선택지가 될 것입니다.

리액트에서는 컴포넌트라는 개념이 매우 중요합니다. 컴포넌트에 대해서 확인해보고 이와 더불어 state와 props에 대한 내용도 확인해 봅시다.

React 컴포넌트란?

React에서 컴포넌트는 UI를 구성하는 가장 작은 단위로, 독립적이고 재사용 가능한 코드 조각입니다. 이 컴포넌트는 각자 자신의 상태를 관리할 수 있고, 서로 데이터를 주고받으며 동작합니다. 이 컴포넌트는 다음과 같은 두 가지 형태로 작성할 수 있습니다:

  • 함수형 컴포넌트 (Functional Components): 함수 형태로 정의된 컴포넌트.
  • 클래스형 컴포넌트 (Class Components): 클래스를 이용해 정의된 컴포넌트. (최근에는 함수형 컴포넌트와 Hooks를 더 많이 사용함)

함수형 컴포넌트의 예시

const MyComponent = () => {
  return (
    <div>
      <h1>Hello, React!</h1>
    </div>
  );
};

 

컴포넌트에서 STATE

State는 컴포넌트 내에서 변경 가능한 데이터를 관리하는 데 사용됩니다. 예를 들어, 사용자 입력, 버튼 클릭 등으로 인해 변할 수 있는 값을 다룰 때 useState 훅을 사용합니다. 쉽게 이야기하면 변수와 비슷한 개념이라고 생각하면 쉬울 거 같습니다.

import React, { useState } from 'react';

const Counter = () => {
  // useState로 count 상태 선언
  const [count, setCount] = useState(0);

  return (
    <div>
      <h1>Count: {count}</h1>
      {/* 버튼 클릭 시 count 상태 변경 */}
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

export default Counter;

 

  • useState는 현재 상태(count)와 상태를 업데이트하는 함수(setCount)를 반환합니다.
  • 위 예시에서 버튼을 클릭할 때마다 count 값이 1씩 증가하고, 그 값이 화면에 즉시 반영됩니다.

컴포넌트에서 Props

Props는 부모 컴포넌트가 자식 컴포넌트에 데이터를 전달하는 방법입니다. Props는 읽기 전용이므로 자식 컴포넌트에서 이를 직접 변경할 수 없습니다.

// 자식 컴포넌트
const Greeting = ({ name }) => {
  return <h1>Hello, {name}!</h1>;
};

// 부모 컴포넌트
const App = () => {
  return (
    <div>
      {/* Props로 name 값을 자식 컴포넌트에 전달 */}
      <Greeting name="React" />
    </div>
  );
};

export default App;

 

 

  • Greeting 컴포넌트는 name이라는 props를 받으며, 이를 통해 인사말을 출력합니다.
  • 부모 컴포넌트인 App은 Greeting에 name="React"라는 값으로 props를 전달하고, 자식 컴포넌트는 이를 출력할 뿐 수정할 수 없습니다.

State와 Props의 차이점

  • State는 컴포넌트 내에서 관리되는 데이터로, 주로 사용자 상호작용을 처리할 때 사용됩니다.
  • Props는 부모에서 자식으로 전달되는 읽기 전용 데이터로, 컴포넌트 간 데이터 흐름을 관리하는 데 사용됩니다.

State와 Props를 함께 사용하는 예시

import React, { useState } from 'react';

// 자식 컴포넌트
const DisplayCount = ({ count }) => {
  return <h2>Current Count: {count}</h2>;
};

// 부모 컴포넌트
const CounterApp = () => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <h1>Counter</h1>
      {/* State를 자식 컴포넌트로 전달 */}
      <DisplayCount count={count} />
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

export default CounterApp;

 

 

 

패키지 매니저(Package Manager)

리액트로 개발을 하다보면 npm이라던가 yarn이라던가 하는 것들을 반드시 보게된다. 

얘들은 뭐길래 사용해야하는 걸까? 

 

이들은 패키지 매니저라고 불리는 것들이다. 말그대로 패키지를 관리하는 도구로서 프로젝트에서 라이브러리, 프레임워크, 모듈 등의 패키지를 관리한다. node.js에서는 흔히 npm과 yarn을 자주 사용한다. 이들은 웹사이트에서 패키지를 다운로드하여 컴퓨터에 설치를 해준다.

간단하게 이야기 하자면 설치된 프로그램을 관리하는 프로그램이다. 

 

그렇다면 node.js에서 가장 많이 사용되는 npm과 yarn은 어떤 차이를 가지고 있는 걸까?

NPM

npm은 node.js와 함께 2009년에 처음 출시된 패키지를 쉽게 설치하고 관리하기 위해 설계된 패키지 관리자이다.

명령어로는 다음과 같은 것들이 있다.

npm install <package>: 패키지 설치.
npm init: 새로운 프로젝트 초기화.
npm install 또는 npm i: package.json에 명시된 모든 패키지 설치.
npm update: 패키지 업데이트.

 

기능으로 package.json파일을 사용하여 프로젝트에 필요한 패키지와 그 버전을 관리한다. 기본적으로 중앙화된 npm레지스트리에서 패키지를 설치한다. 또 많은 패키지 관리와 배포에 사용된다. 

Yarn

yarn은 yet another resource negotiator의 약자로 2016년에 facebook이 npm의 성능과 보안 문제를 해결하기 위해 만든 패키지 관리자이다. npm과 호환이되며, 같은 기능을 제공하지만 성능과 안정성을 개선하려는 목적을 가지고 있다. 

 

명령어는 다음과 같다.

yarn add <package>: 패키지 설치 (npm의 install에 해당).
yarn init: 새로운 프로젝트 초기화.
yarn install: package.json 또는 yarn.lock 파일에 명시된 모든 패키지 설치.
yarn upgrade: 패키지 업데이트.

 

yarn 은 yarn.lock파일을 통해 설치된 모든 패키지의 정확한 버전을 고정하여 의존성 충돌을 방지하고 병렬설치 및 캐싱을 통해 빠른 속도록 패키지 설치가 가능하다. 오프라인 모드를 지원하고 이미 설치된 패키지를 네트워크 없이도 다시 설치가 가능하다 .

 

npm과 yarn의 차이점

출시일 2009년 2016년
속도 패키지 설치 속도가 느린 편 병렬 설치와 캐싱 덕분에 빠름
lock 파일 package-lock.json yarn.lock 파일을 사용하여 더 안정적인 의존성 관리
명령어 npm install, npm update 등 yarn add, yarn upgrade 등
보안 npm 자체적으로는 일부 보안 문제가 있었으나 최근 개선됨 Yarn은 npm보다 초기부터 보안성을 강조하여 더 안전함
오프라인 설치 제한적 네트워크 없이 오프라인 설치가 가능
커뮤니티 및 지원 매우 큰 커뮤니티와 지원 npm에 비해 작지만 꾸준히 성장하는 커뮤니티
패키지 해시 패키지 무결성 검사를 제공하지 않음 패키지의 해시 검사를 통해 무결성 보장

 

결론

  • npm: 기본적으로 Node.js와 함께 제공되며, 전 세계적으로 가장 많이 사용되는 패키지 관리자이다. 많은 프로젝트에서 안정적으로 사용되고 있으며, 최근 버전에서는 성능과 보안이 많이 개선되었다.
  • Yarn: npm의 성능과 보안 문제를 해결하기 위해 만들어진 대안으로, 특히 빠른 설치 속도와 의존성 관리에서 강점을 보인다. 대규모 프로젝트나 팀 협업에서 더 일관된 환경을 제공할 수 있다.

두 도구 모두 JavaScript 프로젝트에서 패키지 관리를 쉽게 해주지만, 프로젝트 규모나 속도에 민감하다면 Yarn을 사용하는 것이 유리할 수 있습니다. 하지만 둘 다 매우 유사하므로, 개인의 선호나 프로젝트 요구 사항에 따라 선택하면 된다.

토스트 노티피케이션은 어떤 동작에 대한 피드백을 나타내는 것을 뜻합니다

이번 포스트에서는 버튼을 눌렀을 때 그 동작에 대한 반응을 확인 하라 수 있는 toast notification을 만들어 보려고 합니다. 

 

 

저기 위에 버튼들을 누르면 해당 토스트들이 생성이 됩니다. 

그리고 timeout을 걸어서 시간이 되면 사라지게 만들었습니다. 

함께 코드 보면서 진행해봅시다. 

 


ToastBox와 메시지 변수 선언 

let toastBox = document.getElementById("toastBox");
let successMsg = '<i class="fa-solid fa-circle-check"></i>successfully submitted';
let errorMsg = '<i class="fa-solid fa-circle-xmark"></i>Please fix the error';
let invalidMsg = '<i class="fa-solid fa-circle-exclamation"></i>Invalid input, check again';

- 먼저 toastBox라는 ID를 가진 변수를 가져옵니다. toastBox는 동적으로 생성될 알람(toast)메시지를 담는 역할을 합니다. 

successMsg, errorMsg, invalidMsg는 각각 성공, 에러, 그리고 잘못된 입력에 대한 알림 메시지를 Html코드와 함께 문자열로 저장합니다. 

 

showToast함수 정의 

function showToast(msg) {
  let toast = document.createElement("div");
  toast.classList.add("toast");
  toast.innerHTML = msg;
  toastBox.appendChild(toast);
  if (msg.includes("error")) {
    toast.classList.add("error");
  }
  if (msg.includes("invalid")) {
    toast.classList.add("invalid");
  }
  setTimeout(() => {
    toast.remove();
  }, 6000);
}

- 버튼을 누르면 발생하게 되는 showToast( )함수입니다. 

- document.createElement('div')를 사용해 새로운 div요소를 생성합니다. 이 요소는 동적으로 생성되는 알림의 컨테이너 역할을 수행합니다 .

- toast.classList.add('toast')는 이 div요소에 toast라는 css클래스를 추가해, 알림에 대한 스타일을 지정할 수 있게 합니다. 

- toast.innerHTML=msg는 함수에 전달된 메시지(msg)를 div안에 넣는 역할을 합니다. 

- 마지막으로 toastBox.appendChild(toast)는 생성된 toast를 toastBox안에 추가해 화면에 표시되게 합니다. 

 

메시지에 따른 추가 클래스 지정 

- error라는 단어가 포함되어 있으면 toast요소에 error라는 클래스를 추가합니다. 

- Invalid라는 요소가 포함되어 있으면 invalid클래스를 추가해 입력이 잘못된 경우 별도로 스타일링 할 수 있도록 합니다. 

 

알림 자동 제거 

setTimeout(() => {
  toast.remove();
}, 6000);

- setTimeout함수를 이용해 6초(6000ms)후에 toast요소를 자동으로 제거하는 역할을 합니다. 알림 메시지가 일정 시간 후에 자동을 ㅗ사라지게 하기 위한 설정된 일부입니다. 

 

이러한 방식으로 사용자가 알림을 확인한 뒤 일정 시간이 지나면 자동으로 사라져 화면이 깔끔하게 유지될 수 있습니다. 

 

 

'개발 > javascript' 카테고리의 다른 글

[JS]QR code생성기 (qrcode generator)  (2) 2024.09.18
[JS] 인용구 생성기(quotable generator)  (1) 2024.09.13
[JS]나이 계산기  (0) 2024.09.10
[JS] 노트 앱 만들기!  (0) 2024.09.09
[JS]랜덤 패스워드 생성기!!  (1) 2024.09.09

우리 일상에서 qr코드는 흔하게 사용되는 기술이고 매우 유용하게 사용되고 있습니다

간편하게 신원을 조회하거나 사이트에 접근하기 편하기 때문인거 같아요 

 

그 qr코드를 어떤 식으로 만드는 지 실습을 통해 알아보도록 하겠습니다

 

이 프로그램에 들어가게되면 텍스트나 url을 입력하는 Input창과 생성하기 버튼이 먼저 눈에 들어옵니다. 

input에 원하는 사이트를 입력하면 해당 사이트에 대한 qr코드가 생성이됩니다.

이 qr코드가 잘 생성이 된건지 확인 해보기 위해서 카메라를 통해 확인을 해보았습니다. 

오호라 사이트가 뜨는 걸 보니 잘 작동이 되고 있습니다.


이번에는 어떤식으로 코드가 진행이되었는지 살펴 보도록 하겠습니다.

1. 변수 선언 및 DOM 요소 선택

let imgBox = document.getElementById("ImgBox");
let qrImage = document.getElementById("qrImage");
let imgText = document.getElementById("qrText");

이 프로젝트에서 사용되는 변수들은 다음과 같습니다. 

- imgbox는 QR코드가 생성될 때 이미지를 보여줄 <div id="imgBox">입니다. 나중에 이 div에 show-img클래스를 추가하여 이미지가 보이도록 제어할 수 있습니다. 

- qrImage는 <img>태그로 QR코드 이미지가 표시될 곳으로 사용자가 입력한 텍스트로 QR코드를 생성한 후, 이 태그의 src속성을 변경해 이미지가 나타나게 됩니다. 

- imgText는 사용자가 텍스트 또는 URL을 입력하는 input필드를 선택합니다. 이 값을 읽어서 qr코드를 생성하는데 사용합니다. 

2. QR 코드 생성 함수 (generateQR)

function generateQR() {
  if (qrText.value.length > 0) {
    qrImage.src =
      "https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=" +
      qrText.value;
    imgBox.classList.add("show-img");
  } else {
    qrText.classList.add("error");
    setTimeout(() => {
      qrText.classList.remove("error");
    }, 1000);
  }
}

generatorQR함수는 QR코드 생성버튼을 눌렀을 때 호출됩니다. 

 

1. 입력값 확인 

if(qrText.value.length>0)

사용자가 텍스트 또는 URL을 입력했는지 확인하는 조건문입니다. 만약 입력 값이 있다면 QR코드를 생성하는 단계로 넘어가고, 입력값이 없으면 오류처리가 실행됩니다. 

 

2. QR코드 생성 및 이미지 업뎃

qrImage.src =
  "https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=" +
  qrText.value;

입력값이 있을 경우 QR코드 이미지를 생성합니다. qrImage.src는 img태그의 src속성을 변경하여 이미지를 로드하는 역할을 합니다. 여기서 src에 설정된 URL은 QR코드 생성 API인 

https://api.qrserver.com/v1/create-qr-code/

입니다. 여기서 이 API는 size와 data라는 두개의 파라미터를 사용합니다. size=150x150으로 이 사이즈로 코드를 생성합니다. data=뒤에는 사용자가 입력한 텍스트나 URL이 추가됩니다. 즉 입력한 데이터가 QR코드에 인코딩 됩니다. 

 

3. 이미지 박스 표시 

imgBox.classList.add("show-img");

qr코드가 성공적으로 생성되면, imgBox에 show-img클래스를 추가합니다. 이 클래스는 CSS에서 정의된대로 이미지 박스의 max-height값을 늘려 QR코드 이미지를 보여주도록 합니다. 초기에는 이미지 박스의 높이가 0이므로 QR코드가 보이지 않다가 show-img클래스가 추가되면 이미지가 자연스럽게 나타납니다. 

 

4. 오류 처리 

qrText.classList.add("error");
setTimeout(() => {
  qrText.classList.remove("error");
}, 1000);

만약 입력 값이 없다면 qrText에 error클래스를 추가하여 입력 필드가 흔들리는 애니메이션이 적용됩니다. 

이건 css 에서 @keyframes shake로 정의된 애니메이션 입니다. 

setTimeout함수는 1초 후에 error클래스를 제거합니다. 이는 애니메이션이 반복되지 않고 한번만 실행되게 합니다. 

 

 

이번 실습은 생각보다 코드가 짧았지만 유용한 결과를 얻을 수 있었습니다. 

재밌는 실습이었어요 

'개발 > javascript' 카테고리의 다른 글

[JS] Toast Notification  (0) 2024.09.24
[JS] 인용구 생성기(quotable generator)  (1) 2024.09.13
[JS]나이 계산기  (0) 2024.09.10
[JS] 노트 앱 만들기!  (0) 2024.09.09
[JS]랜덤 패스워드 생성기!!  (1) 2024.09.09

안녕하세요 오늘 만들려고 하는 건 인용구를 랜덤으로 생성해주는 앱입니다. 

https://github.com/lukePeavey/quotable

 

GitHub - lukePeavey/quotable: Random Quotes API

Random Quotes API. Contribute to lukePeavey/quotable development by creating an account on GitHub.

github.com

이API를 사용해서 아주 쉽고 간단한 랜덤 인용구를 생성시킬 수 있습니다. 

 


페이지를 열게 되면 "Quote of the day"라는 제목으로 아래 " "안에는 인용구 밑에는 작가 이름이 생성이 됩니다. 

지난 번에 했을 때는 잘됐는데 지금은 잘 안되고 있는게 아마 API문제인것 같아요.. 해결 방법을 아직은 잘 몰라서 일단 그냥 했습니다

 

New Quote버튼을 누르면 새로운 인용이 생성되고 

Tweet을 누르면 X와 연결되서 바로 Tweet할 수 있게 했습니다. 

 

전X계정이 없어서 저건 굳이 안하긴 했는데 글 많이 쓰시는 분들에게는 유용할 수  있다고 생각합니다. 


자 그럼 코드를 확인 해봅시다. 

요소선택 

const quote = document.getElementById("quote");
const author = document.getElementById("author");
const api_url = "https://api.quotable.io/random";

- quote와 author 요소를 선택해서 나중에 인용구와 저자를 표시할 수 있게 합니다. 

- api_url은 랜덤으로 인용구를 가져올 API의 UR을 정의하는 것입니다. 

비동기 함수로 API호출 및 데이터 처리 

async function getquote(url) {
  const response = await fetch(url);
  var data = await response.json();
  console.log(data);
  quote.innerHTML = data.content;
  author.innerHTML = data.author;
}

getquote(api_url);

 

- get quote 함수는 API로부터 인용구 데이터를 비동기적으로 가져옵니다. 

- API는 fetch를 통해 API로부터 데이터를 가져오고 await로 비동기 작업이 완료될 때까지 기다립니다. 

- 데이터 처리는 가져온 데이터를 JSON형식으로 변환하여 인용구와 저자를 HTML요소에 표시합니다. 

 

트위공유 기능 구현

function tweet() {
  window.open(
    "https://twitter.com/intent/tweet?text=" +
      quote.innerHTML +
      " ---- by " +
      author.innerHTML,
    "Tweet Window",
    "width=600,height=300"
  );
}

- tweet함수는 현재 표시된 인용구를 트위터(X)화면에 공유하기 위한 새로운 창을 여는 과정입니다. 

- 트윗 메시지 구성: 인용구와 저자를 포함한 트윗 메시지를 작성하고 window.open을 사용해 트윗 작성 창을 엽니다. 

 

-아, 트위터 공유 기능은

https://developer.x.com/en/docs/x-for-websites/tweet-button/overview

 

Guides

The Tweet button is a small button displayed on your website to help viewers easily share your content on X. A Tweet button consists of two parts: a link to the Tweet composer on x.com and X for Websites JavaScript to enhance the link with the easily rec

developer.x.com

해당 사이트의 코드를 가져와서 추가하였습니다. 

 

버튼을 누를때마다 새로운 인용들이 생성되는게 꽤 재밌더라구요 !

'개발 > javascript' 카테고리의 다른 글

[JS] Toast Notification  (0) 2024.09.24
[JS]QR code생성기 (qrcode generator)  (2) 2024.09.18
[JS]나이 계산기  (0) 2024.09.10
[JS] 노트 앱 만들기!  (0) 2024.09.09
[JS]랜덤 패스워드 생성기!!  (1) 2024.09.09

이번에 만들어 볼 프롤젝트는 태어난 날부터 지금까지 며칠이 지났는지는 계산하는 앱을 만들어 보려고 합니다. 

이 프로젝트에서는 년도별 월별 일별에 따라 계산이 달라지기 때문에 이전 프로젝트들에 비해 조금 더 복잡한 조건문들이 사용되었습니다. 

 

가장 초기화면의 모습입니다. 프로젝트의 이름이 적혀있고 날짜를 지정할 수 있는 창과 버튼이 있습니다.

달력 버튼을 누르게 되면 날짜를 지정할 수 있는 달력이 나타나게 됩니다. 이 프로젝트는 과거의 날짜에서 오늘까지의 날짜를 계산하는 것이기 때문에 오늘 이후의 날짜들은 선택할 수 없게 비활성화가 되어 있습니다.

저는 제 나이를 밝히고 싶지는 않아서 2000년 1월 1일부터 오늘까지의 날을 계산해보았습니다. 

21세기가 된지 벌써 24년 하고도 8개월 9일이나 지나있습니다. 

 

시간이 정말 빠르네요 ㅎㅎ 

그럼 어떤 코드들이 사용되어 있는지 확인해 봅시다. 


1. HTML요소 선택 및 초기화 

let userInput = document.getElementById("date");
userInput.max = new Date().toISOString().split("T")[0];
let result = document.getElementById("result");
  • let userInput = document.getElementById("date"): date라는 id를 가진 HTML 요소(입력 필드)를 선택하여 userInput이라는 변수에 저장합니다.
  • userInput.max = new Date().toISOString().split("T")[0]: 사용자가 오늘 이후의 날짜를 입력하지 못하도록 max 속성을 오늘 날짜로 설정합니다. new Date().toISOString().split("T")[0] 코드는 현재 날짜를 YYYY-MM-DD 형식으로 변환하는 역할을 합니다.
  • let result = document.getElementById("result"): 결과를 표시할 result라는 id를 가진 HTML 요소를 선택하여 result 변수에 저장합니다.

2. 나이계산함수 CalculateAge()

function calculateAge() {
  let birthDate = new Date(userInput.value);
  let d1 = birthDate.getDate();
  let m1 = birthDate.getMonth() + 1;
  let y1 = birthDate.getFullYear();

  let today = new Date();

  let d2 = today.getDate();
  let m2 = today.getMonth() + 1;
  let y2 = today.getFullYear();

  let d3, m3, y3;
  y3 = y2 - y1;
  if (m2 >= m1) {
    m3 = m2 - m1;
  } else {
    y3--;
    m3 = 12 + m2 - m1;
  }
  if (d2 >= d1) {
    d3 = d2 - d1;
  } else {
    m3--;
    d3 = getDaysInMonth(y1, m1) + d2 - d1;
  }
  if (m3 < 0) {
    m3 = 11;
    y3--;
  }
  result.innerHTML = `You are <span>${y3}</span> years,<span>${m3}</span> months and <span>${d3}</span> days old`;
}

 

  • function calculateAge() { ... }: 이 함수는 사용자가 입력한 생년월일(userInput.value)을 받아 현재 나이를 계산하고, 그 결과를 HTML 요소에 표시합니다.
  • let birthDate = new Date(userInput.value);: 사용자가 입력한 생년월일을 Date 객체로 변환하여 birthDate 변수에 저장합니다.
  • let d1 = birthDate.getDate(): birthDate 객체에서 일을 추출합니다.
  • let m1 = birthDate.getMonth() + 1: birthDate 객체에서 월을 추출합니다. (자바스크립트에서 월은 0부터 시작하므로 +1을 해줍니다.)
  • let y1 = birthDate.getFullYear(): birthDate 객체에서 연도를 추출합니다.
  • let today = new Date(): 현재 날짜를 나타내는 Date 객체를 생성합니다.
  • let d2 = today.getDate(): 현재 날짜에서 일을 추출합니다.
  • let m2 = today.getMonth() + 1: 현재 날짜에서 월을 추출합니다.
  • let y2 = today.getFullYear(): 현재 날짜에서 연도를 추출합니다.
  • let d3, m3, y3: 나이 계산을 위한 변수를 선언합니다.
  • y3 = y2 - y1: 기본적으로 현재 연도에서 출생 연도를 빼서 나이를 계산합니다.
  • if (m2 >= m1) { ... } else { ... }: 생월과 현재 월을 비교하여 만 나이를 계산합니다. 현재 월이 생월보다 이전이면 나이를 한 살 줄여줍니다.
  • if (d2 >= d1) { ... } else { ... }: 생일과 현재 일을 비교하여 월을 조정합니다. 현재 일이 생일보다 이전이면 한 달을 빼고 일수를 조정합니다.
  • if (m3 < 0) { ... }: 월 계산 후 월이 음수로 나오면 11개월로 설정하고 나이를 한 살 줄여줍니다.
  • result.innerHTML = ...: 최종적으로 계산된 나이(년, 월, 일)를 HTML 요소에 표시합니다.

3.월별 일수 계산 함수 

function getDaysInMonth(year, month) {
  return new Date(year, month, 0).getDate();
}

 

  • function getDaysInMonth(year, month) { ... }: 특정 연도와 월에 해당하는 일수를 계산하는 함수입니다.
  • return new Date(year, month, 0).getDate(): 주어진 연도와 월에 맞는 마지막 날짜를 반환합니다. 여기서 new Date(year, month, 0)은 지정된 월의 마지막 날을 의미합니다.

이렇게 하면 완성입니다!

'개발 > javascript' 카테고리의 다른 글

[JS]QR code생성기 (qrcode generator)  (2) 2024.09.18
[JS] 인용구 생성기(quotable generator)  (1) 2024.09.13
[JS] 노트 앱 만들기!  (0) 2024.09.09
[JS]랜덤 패스워드 생성기!!  (1) 2024.09.09
[JS]퀴즈앱 (quiz app)만들기  (0) 2024.09.06

+ Recent posts