기존의 Html과 css로 작업하던 결과물을 JSX및 styled-components로 옮기는 과정에서 느낀 모든것을 서술한다. 본문에서는 모든 내용에 대해 자세히 다루진 않는다. 해당 날짜에 익힌 내용들을 작성하므로 일련의 흐름은 작성자의 궁금증의 흐름으로 보면 된다.
JSX - javascript를 확장한 문법이다. UI가 어떻게 생겼는지 브라우저에게 설명하기 위해 보통 React와 함께 사용된다.
React는 렌더링 로직이 다른 UI 로직과 본질적으로 결합되어 있기 때문에 이벤트 처리 방법, 시간에 따른 상태 변경 방법 및 데이터 표시 준비 방법을 포함한다. 따라서 별도의 파일에 마크업과 로직을 넣어 기술을 인위적으로 분리하지 않고 둘 다 포함하는 컴포넌트라는 유닛을 통해 관심사를 분리 한다.
JSX 안에 자바스크립트 표현식을 {}로 묶어서 포함시킬 수 있다.
React DOM은 기본적으로 렌더링 되기 전에 JSX 내에 포함된 모든 값을 escape하는데 따라서 어플리케이션에 명시적으로 작성되지 않은 내용은 절대 삽입할 수 없다.
Babel은 이 표현식을 javascript코드로 변환하는 라이브러리로 Babel을 통해 DOM은 렌더링 할 수 있게 된다.
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
두 코드는 같은 코드다.
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
JSX는 html의 확장이니 스타일을 적용하려면 css가 필요하다. html과 달리 class가 아니라 className을 통해 css 스타일을 적용할 수 있다. 확장하며 이전과 다른 네이밍을 사용하는 부분이 생겼다. 특히 HTML에서는 이벤트 핸들러를 소문자로 작성하지만, JSX에서는 카멜케이스로 작성한다. JSX에서는 속성 이름이 JavaScript 객체의 키로 변환되기 때문이다.
<input type="checkbox">에서 초기 체크 상태를 설정하는 속성. <input type="checkbox" defaultChecked /><input> 또는 <textarea>에서 초기 값을 설정하는 속성. <input type="text" defaultValue="Hello" /> <select>
<option value="1">Option 1</option>
<option value="2" defaultSelected>Option 2</option>
</select> <form action="/submit" formAction="https://example.com/submit">
<input type="submit" value="Submit" />
</form> <form encType="multipart/form-data">
<input type="file" />
</form> <form method="post" formMethod="POST">
<input type="submit" value="Submit" />
</form> <form target="_blank" formTarget="_self">
<input type="submit" value="Submit" />
</form> <form noValidate formNoValidate>
<input type="text" required />
<input type="submit" value="Submit" />
</form>onclick -> onClick
<button onClick={handleClick}>Click Me</button>
tabindex -> tabIndex
<div tabIndex="0">Focusable Div</div>
maxlength -> maxLength
<input type="text" maxLength="10" />
readonly -> readOnly
<input type="text" readOnly />
colspan -> colSpan
<table>
<tr>
<td colSpan="2">Merged Columns</td>
</tr>
</table>
aria-, data- 속성들
ARIA(Accessible Rich Internet Applications) 속성들과 data속성들은 HTML과 동일하게 aria-label, aria-hidden 등의 형태로 사용되므로 주의한다.
<button aria-label="Close">X</button> {/* aria */}
<div data-id="123">Custom Data</div> {/* data */}
특별한 주의가 필요한 속성들
style 속성: JSX에서 style 속성은 문자열이 아니라 JavaScript 객체로 전달해야 하고 마찬가지로 카멜케이스로 변환된다.
<div style={{ backgroundColor: 'blue', fontSize: '14px' }}>Styled Div</div>
클라이언트 사이드 라우팅을 관리하기 위한 라이브러리로 사용자가 URL 변경 시 페이지를 새로고침하지 않고도 다른 페이지로 전환할 수 있게 된다. 예를 들어 /home 경로로 접근하면 root 밑에 있는 home component를 렌더링 하도록 지정이 가능하다.
👉 참고사이트
주요 기능은 다음과 같다.
1. 기본적인 Route: 각 URL 경로에 대응하는 컴포넌트 지정
2. 네비게이션: link 클릭 시 다른 페이지로 전체 페이지 새로 고침 없이 이동.
3. 동적 경로 매칭: 특정 URL 패턴 정의, 경로에 포함된 매개변수를 컴포넌트에서 사용가능. ex) /user/:id와 같은 경로를 정의하면 특정 사용자 ID에 따라 다른 콘텐츠를 렌더링 가능
4. 리다이렉션(Redirection): 특정 조건에 따라 사용자를 다른 경로로 리다이렉트 가능하다. ex) 사용자가 로그인 하지 않았을 때 로그인 페이지로 리다이렉트 하는 경우
BrowserRouter: 브라우저 히스토리 Api사용으로 URL관리하는 기본적 라우터 컴포넌트
Routes: Route 컴포넌트를 감싸서 URL에 맞는 컴포넌트 렌더링
Route: 특정 URL 경로와 해당 경로에 대응하는 컴포넌트 지정
Link: 전체 페이지 새로고침 없이 경로를 변경하여 다른 페이지 이동이 가능
useNavigate: javascript로 페이지 이동을 처리할 수 있게 하는 훅
useParams: 현재 경로의 동적 파라미터를 가져오기 위한 훅 - 동적 경로 매칭
useLocation: 현재 경로, 검색 문자열, 해시 등 URL에 대한 정보를 가져오는 훅
useMatch: 경로와 일치하는 지 여부 확인 후 일치하면 매칭된 경로 정보를 반환
Navigate: 특정 조건 충족 시 지정된 경로로 리다이렉트하는 컴포넌트
👉 hook?: 함수형 컴포넌트에서도 상태 관리 및 side effect를 처리할 수 있도록 해주는 함수
import React, { useState } from 'react';
function Example() {
// "count"라는 새로운 상태 값을 정의합니다.
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
Blob은 JavaScript에서 바이너리 데이터(파일, 이미지, 오디오 등)를 처리하고 관리할 수 있는 유용한 객체로 이를 통해 브라우저에서 다양한 종류의 데이터를 다루고, 파일을 생성하거나 다운로드하는 작업을 쉽게 수행할 수 있다. 예시코드는 다음과 같다.
// 텍스트 데이터를 Blob 객체로 생성
const text = "Hello, World!";
const blob = new Blob([text], { type: 'text/plain' });
// Blob 객체를 URL로 변환하여 다운로드 링크를 생성
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'hello.txt';
document.body.appendChild(a);
a.click();
// URL 객체를 해제하여 메모리 누수를 방지
URL.revokeObjectURL(url);
Tailwind CSS는 유틸리티-퍼스트(Utility-First) CSS 프레임워크로 HTML 클래스 이름을 통해 스타일링을 적용가능하다. 인라인에서 빠르게 스타일을 정의할 수 있어서 CSS를 한 줄도 작성하지 않고 완전한 사용자 정의 구성요소 디자인을 만드는 것이 가능하며 tailwind.config.js라는 독립 클래스를 사용하여 모듈 및 높은 재사용성을 가진다. 또한 인라인으로 클래스를 적용하므로 스타일링의 변화를 바로 확인할 수 있다.
따라서 다음과 같이 특징을 정의할 수 있다.
1. 유틸리티 클래스 기반
2. 모듈성과 높은 재사용성
3. 즉각적인 피드백
더 자세한 내용은 해당 블로그를 참조하면 되겠다.
vscode에서 진행하려면 plugin 설정을 하면 된다. plugin이 싫다면 아래 명령어를 terminal에 입력하여 진행할 수 있다.
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init
plugin 설정은 이렇게 진행한다.
👍 그냥 좋은 거 다 때려박고 싶다면 Tailwind CSS Extension Pac을 설치하면 된다.

1. tailwind css intellisense를 install 후
2. Ctrl + Shipt + P 에서 Open User Setting(Json) 을 찾아서 연다.
해당 velog에 react 및 react native에 설정하는 방법에 대해서 자세하게 나와 있다.
플러그인 종류는 이 velog를 참조하였다.
react 및 react native를 설정하는 velog에 잘 나와있지만 자동완성은 적용할 수 있도록 아래 세팅은 반드시 해 주는 것을 권장한다.
// user setting에 자동완성을 위해 추가
"files.associations": {
"*.css": "tailwindcss" // CSS 파일을 Tailwind CSS로 인식하도록 설정
},
"editor.quickSuggestions": {
"strings": true // 문자열 내에서 자동 완성을 활성화
}
styled-components는 CSS in JS로 스타일 정의를 CSS 파일이 아닌 Javascript로 작성된 컴포넌트에 바로 삽입하는 스타일 기법이다. 해당 기법을 통해 스타일을 컴포넌트 단위로 관리할 수 있고 javascript 코드와 밀접하게 결합되므로 컴포넌트의 동적 스타일링이 용이해진다.
Tailwind.js와 헷갈리면 안되는 부분은 tailwind는 tag 자체에다가 스타일을 지정할 수 있고 styled-components의 경우에는 따로 javascript안에서 style을 지정하고 해당 style을 태그에 적용해서 사용하는 것이다.
CSS-in-JS의 특징은 다음과 같다.
styled-components의 특징은 다음과 같다.
| 특성 | styled-components | Tailwind CSS |
|---|---|---|
| 스타일링 방식 | CSS-in-JS, JavaScript 내에서 CSS 작성 | Utility-First CSS, 미리 정의된 클래스를 HTML에 직접 사용 |
| 동적 스타일링 | props나 상태에 따라 JavaScript에서 동적 스타일링 가능 | 유틸리티 클래스를 조합하여 정적 스타일링, 동적 스타일링은 JavaScript로 클래스 조작 |
| 모듈성 및 스코핑 | 각 컴포넌트에 고유한 스타일이 적용, 자동 스코핑 | 모든 유틸리티 클래스가 전역적으로 사용되며 충돌이 없도록 설계됨 |
| 가독성 | 스타일과 로직이 함께 있어서 가독성이 떨어질 수 있음 | HTML과 같은 코드 내에서 스타일을 바로 확인 가능 |
| 파일 관리 | 스타일이 JavaScript 파일 내에 포함됨 | 별도의 CSS 파일 없이 HTML/JSX 내에서 직접 스타일 작성 |
| 배포 및 빌드 | 스타일이 JavaScript 번들에 포함됨 | PurgeCSS와 같은 도구로 사용하지 않는 CSS를 제거하여 최적화 가능 |
Tailwind CSS와 styled-components를 같이 사용하는 것은 코드스타일이 다르기 때문에 코드베이스가 복잡해 질 수 있다. 따라서 같이 사용하는 것은 지양하는 것이 좋아 보이나. 이전에 styled-components로 작성되어 있던 것을 tailwind로 변경시켜 작업해야 하기 때문에 둘 다 사용해보고 변경사항을 적용해보자 한다.
🤗 특징 및 장점:
호이스팅: 함수 선언식은 호이스팅(hoisting)의 영향을 받아 코드에서 함수가 선언되기 전에 호출할 수 있습니다. 이는 큰 코드베이스에서 함수 호출 위치를 더 자유롭게 설정할 수 있게 한다.
가독성: 함수 이름이 명확하게 드러나므로, 코드를 읽을 때 함수의 목적을 쉽게 이해할 수 있습니다. 전통적인 방식으로 함수를 정의하기 때문에 많은 개발자들에게 익숙하다.
일반적인 사용 사례: 컴포넌트가 매우 단순하거나, 함수 선언식으로 작성된 기존 코드베이스에서 일관성을 유지하고자 할 때 사용된다.
-> 사용하기 좋은 경우
Function Expression (함수 표현식) / Arrow Function (화살표 함수)
🤗 특징 및 장점:
간결성: 화살표 함수는 문법이 간결하고, 특히 콜백 함수나 인라인 함수로 사용할 때 유용하다.
this 바인딩: 화살표 함수는 자신만의 this를 가지지 않고, 상위 스코프의 this를 자동으로 바인딩합니다. 따라서 클래스 메서드나 콜백 함수에서 this 문제를 피할 수 있다.
익명 함수로 사용: 함수 표현식은 함수가 정의된 위치에서 바로 사용할 수 있으며, 다른 변수나 함수의 인자로 전달하기에 좋다.
일반적인 사용 사례: React 컴포넌트나 함수가 간단할 때, 특히 클래스 내부 메서드 정의나 콜백 함수 정의 시 자주 사용된다.
-> 사용하기 좋은 경우
결론적으로는 이렇게 나눠서 사용하면 될 것 같다.
Function Declaration: 전통적인 함수 정의 방법을 선호하거나, 코드베이스에서 일관성을 유지하고 싶을 때 사용한다. 함수 이름이 중요한 경우나 함수 호출 순서에 제약이 없는 경우에 적합.
Arrow Function: 간결한 문법과 this 바인딩 문제를 피하고자 할 때 사용하며 특히 React 컴포넌트 정의나 클래스 내부 메서드로서 이벤트 핸들러를 작성할 때 유용하다.