포트폴리오 사이트 만들기 - React
소개
안녕하세요! 웹스토리보이입니다. 이번에는 리액트 작업을 위한 기본적인 설정을 시작하겠습니다. 페이지가 하나밖엔 없지만 페이지 셋팅을 할 거구요! 컴퍼넌트를 설정하여 페이지 구성을 할 것입니다. 또한 CSS를 SCSS로 변경하여 사용하도록 해보겠습니다. 처음하시는 분들은 많이 어색할 수 있지만, 몇 번 따라하다보면 익숙해지고 쉬어집니다. 그럼 시작해 보겠습니다.🧐
인덱스
VITE SITE
- 1. 셋팅하기
- 1_1. vite 설치하기
- 1_2. vite 폴더 정리하기
- 1_3. gsap/lenis 설치하기
- 1_4. git 연동하기
- 2. 레이아웃
- 2.1 레이아웃 구조 만들기
- 2.2 메인 레이아웃 구조 만들기
- 2.3 CSS 셋팅하기
- 2.4 JavaScript 셋팅하기
- 3. 헤더 영역
- 3.1 헤더 구조 잡기
- 3.2 헤더 디자인 설정
- 3.3 반응형 작업하기
- 3.4 메뉴 자바스크립트 설정
- 4. 인트로 영역
- 4.1 인트로 구조 잡기
- 4.2 인트로 디자인 설정
- 4.3 반응형 작업하기
- 5. 스킬 영역
- 5.1 스킬 구조 잡기
- 5.2 스킬 디자인 설정
- 5.3 반응형 작업하기
- 6. 사이트 영역
- 6.1 사이트 구조 잡기
- 6.2 사이트 디자인 설정
- 6.3 반응형 작업하기
- 7. 포트폴리오 영역
- 7.1 사이트 구조 잡기
- 7.2 사이트 디자인 설정
- 7.3 반응형 작업하기
- 7.4 스크립트 작업하기
- 8. 연락처 영역
- 8.1 연락처 구조 잡기
- 8.2 연락처 디자인 설정
- 8.3 반응형 작업하기
- 9. 푸터 영역
- 9.1 푸터 구조 잡기
- 9.2 푸터 디자인 설정
- 9.3 반응형 작업하기
- 10. 마무리
- 10.1 스무스 효과주기
- 10.2 링크 연결하기
- 10.3 netlify에 배포하기
REACT SITE
- 1. 셋팅하기
- 1_1. React 설치하기
- 1_2. React 폴더 정리하기
- 1_3. 라이브러리 설치하기
- 1_4. git 연동하기
- 2. 라우팅 및 컴퍼넌트
- 2_1. 라우팅 설정하기
- 2_2. 컴퍼넌트 설정하기
- 2_3. SCSS 설정하기
2. 라우팅 및 컴퍼넌트
2_1. 라우팅 설정하기
react-router-dom
은 React.js 기반의 웹 애플리케이션에서 라우팅(주소)을 관리하기 위한 라이브러리입니다.
리액트는 한 페이지로 구성된 SPA이기 때문에 주소 페이지가 없습니다.
해당 컴퍼넌트만 불러오기 때문에 이때 페이지가 있는 것처럼 해주기 위해서 리액트용 주소를 처리해주는 방식으로 이 라이브러리를 사용합니다.
SPA(단일 페이지 애플리케이션)는 웹 애플리케이션의 설계 패턴 중 하나로, 하나의 HTML 페이지를 기반으로 동적으로 콘텐츠를 변경하여 사용자와 상호작용하는 웹 애플리케이션을 구현하는 방법입니다. SPA는 전통적인 다중 페이지 애플리케이션(MPA, Multi-Page Application)과는 다른 웹 애플리케이션 구조를 가지고 있습니다.
- 단일 페이지 : SPA는 하나의 HTML 페이지로 시작하고, 페이지 전환 시에도 새로운 HTML을 서버로부터 불러오지 않습니다. 대신, 필요한 데이터와 콘텐츠를 비동기적으로 불러와서 동적으로 페이지를 업데이트합니다. 이로 인해 초기 로딩 속도가 빨라지고, 사용자 경험이 향상됩니다.
- 동적 로딩 : SPA는 초기에 필요한 모든 리소스(스크립트, 스타일시트 등)를 불러온 후, 필요한 데이터만을 요청하여 동적으로 페이지를 구성합니다. 이는 필요한 리소스를 미리 불러와 사용자가 다른 페이지로 이동할 때 렌더링 지연을 최소화하고, 부분적인 페이지 업데이트를 수행할 수 있게 합니다.
- 클라이언트 측 렌더링 : SPA는 주로 클라이언트 측에서 페이지를 렌더링합니다. 서버 측에서는 데이터만을 전달하며, 클라이언트에서 페이지의 구조와 렌더링을 처리합니다. 이로 인해 서버 부하가 줄어들고, 클라이언트 측에서 유연한 UI를 구성할 수 있습니다.
- 상태 관리 : SPA는 클라이언트 측에서 상태를 관리하기 쉽습니다. 주로 리액트와 같은 라이브러리나 프레임워크를 사용하여 상태 관리를 용이하게 처리할 수 있습니다.
- 빠른 UIUX : SPA는 페이지 전환 시 화면이 깜박이지 않고, 새로운 페이지가 빠르게 로딩되는 등 사용자 경험이 좋습니다.
- 루트 URL : SPA는 주로 루트 URL 하나로 시작하며, 이후 URL의 경로에 따라 다른 컴포넌트나 뷰를 렌더링합니다. 이로 인해 라우팅(Routing)이 중요한 역할을 합니다.
- 모바일 앱과 유사한 경험: SPA는 네이티브 모바일 앱과 유사한 사용자 경험을 제공할 수 있습니다. 이를 통해 웹 앱을 모바일 환경에서도 자연스럽게 사용할 수 있습니다.
App.js
는 다음과 같이 설정합니다.
import React from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import HomeView from "./views/HomeView";
const App = () => {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<HomeView />} />
</Routes>
</BrowserRouter>
);
};
export default App;
- import React from "react"; : 이 부분은 리액트를 사용하기 위해 리액트 라이브러리를 불러오고 있습니다. 이렇게 하면 리액트의 기능과 컴포넌트를 사용할 수 있습니다.
- import { BrowserRouter, Route, Routes } from "react-router-dom"; : 이 부분은 react-router-dom에서 필요한 모듈들을 불러오고 있습니다. BrowserRouter, Route, Routes는 라우팅을 구현하는 데 필요한 컴포넌트들입니다.
- import HomeView from "./views/HomeView"; : HomeView라는 이름으로, "./views/HomeView" 경로에 있는 컴포넌트를 불러오고 있습니다. 이는 HomeView 컴포넌트가 해당 경로에 있는 파일에서 정의되어 있다는 것을 의미합니다.
- const App = () => { ... }; : 이는 화살표 함수(arrow function)로 정의된 함수형 컴포넌트입니다. 이 함수형 컴포넌트는 리액트 애플리케이션의 최상위 컴포넌트로, 라우팅 설정을 포함하고 있습니다.
- <BrowserRouter> : BrowserRouter는 라우팅을 적용하기 위한 컴포넌트입니다. 애플리케이션의 최상위 컴포넌트인 App 컴포넌트를 감싸서 라우팅 설정을 적용할 수 있도록 합니다.
- <Routes> : Routes는 라우트들을 정의하는 컨테이너입니다. 각각의 <Route> 컴포넌트들을 <Routes> 컴포넌트 내부에 정의하여 경로와 컴포넌트를 매핑합니다.
- <Route path="/" element={<HomeView />} /> : 이 부분은 "/" 경로에 해당하는 <HomeView> 컴포넌트를 렌더링하도록 설정하는 것입니다. path 속성에는 경로를 지정하고, element 속성에는 해당 경로에 렌더링할 컴포넌트를 JSX 문법으로 전달합니다.
리액트(React) 컴포넌트는 리액트 라이브러리를 통해 사용자 인터페이스(UI)를 구성하는 데 사용되는 기본적인 블록입니다. 컴포넌트는 UI를 작은 재사용 가능한 조각들로 나누어 관리함으로써 코드의 가독성과 유지보수성을 높이는 데 도움을 줍니다. 리액트 컴포넌트는 클래스형 컴포넌트와 함수형 컴포넌트 두 가지 형태로 정의할 수 있습니다.
- 클래스형 컴포넌트 (Class Components) : ES6 클래스로 정의, React.Component를 상속, render() 메서드를 사용하여 UI를 정의, 내부적으로 상태(state)를 가질 수 있음, 생명주기 메서드를 활용하여 컴포넌트의 생성, 갱신, 소멸과 관련된 작업을 처리할 수 있습니다.
- 함수형 컴포넌트 (Functional Components) : JavaScript 함수로 정의, 리액트 16.8 버전 이후에는 훅(hook) 기능이 도입되면서 주로 함수형 컴포넌트가 사용, return 문을 사용하여 UI를 정의, 내부적으로 상태(state)를 가질 수 있음, 상태(state)를 직접 사용할 수 없지만, useState와 같은 훅을 사용하여 상태를 관리할 수 있음, 생명주기 메서드를 사용하지 않습니다.
리액트 컴포넌트는 작은 부분들로 쪼개어 사용되며, 이들을 조합하여 복잡한 UI를 구성합니다.
컴포넌트 간에는 데이터를 전달하기 위해 props
를 사용하며, 자체적인 상태를 관리하기 위해 state
를 사용합니다.
props
는 부모 컴포넌트에서 자식 컴포넌트로 전달되는 읽기 전용 데이터이고, state
는 컴포넌트 내부에서 변경 가능한 데이터입니다.
리액트의 가장 큰 장점 중 하나는 컴포넌트들을 재사용 가능하게 구성하여 개발 생산성을 높일 수 있다는 점입니다. 또한, 가상 DOM(Virtual DOM)을 활용하여 성능을 최적화하고, 상태 변경에 따른 효율적인 렌더링을 수행합니다.
컴포넌트는 리액트 애플리케이션의 기본 단위이며, UI를 구성하는 주된 방법 중 하나입니다. 적절하게 컴포넌트를 설계하고 조합함으로써 모던하고 재사용 가능한 UI를 개발할 수 있습니다.
2_2. 컴퍼넌트 설정하기
페이지가 한페이지이지만 섹션은 7개 구성되어 있기 때문에 컴퍼넌트로 작업을 할 것입니다.
구조는 7개이지만 크게 봤을 때에는 3단 header, main, foooter로 이루어져 있기 때문에
main
컴퍼넌트를 만들겠습니다.
여기에 스킵메뉴를 설정하기 위해 추가적으로 컴퍼넌트를 만들었습니다.
폴더를 구조를 보면 페이지는 views
에 표현이 되고,
컴퍼넌트는 섹션을 구분화시키고 것이고, assets은 기존과 같이 이미지와 css파일을 설정합니다.
constants는 데이터를 보관하는 부분이고 utils은 기타 자바스크립트 파일입니다.
이렇게 세분화하고 시작하겟습니다.
- src
- assets
- components
- Contact.jsx
- Footer.jsx
- Header.jsx
- Intro.jsx
- Main.jsx
- Port.jsx
- Site.jsx
- Skill.jsx
- Skip.jsx
- constants
- utils
- views
- HomeView.jsx
페이지를 나타내는 HomeView.jsx
에는 다음과 같이 작성하겠습니다.
이렇게 HomeView 컴포넌트를 사용하여 홈 페이지의 UI를 구성합니다.
각 컴포넌트들은 기능별로 분리되어 관리되므로, 코드의 가독성과 유지보수성이 좋아집니다.
이렇게 구성된 컴포넌트들을 조합하여 리액트 애플리케이션을 구축할 수 있습니다.
import React from "react";
import Header from "../components/Header";
import Intro from "../components/Intro";
import Skill from "../components/Skill";
import Site from "../components/Site";
import Port from "../components/Port";
import Contact from "../components/Contact";
import Footer from "../components/Footer";
import Skip from "../components/Skip";
import Main from "../components/Main";
const HomeView = () => {
return (
<>
<Skip />
<Header />
<Main>
<Intro />
<Skill />
<Site />
<Port />
<Contact />
</Main>
<Footer />
</>
);
};
export default HomeView;
Contacts.js
파일에는 다음과 같이 기본 소스만 넣어주겠습니다.
import React from "react";
const Contact = () => {
return <div>Contact</div>;
};
export default Contact;
- import React from "react"; : 이 부분은 리액트를 사용하기 위해 리액트 라이브러리를 불러오고 있습니다. 이렇게 하면 리액트의 기능과 컴포넌트를 사용할 수 있습니다.
- const Contact = () => { ... }; : Contact라는 이름의 상수(const)를 선언하고, 이는 화살표 함수(arrow function)로 정의된 함수형 컴포넌트입니다. Contact 컴포넌트는 간단한 화면 요소를 렌더링하는 데 사용됩니다.
- return <div>Contact</div>; : 함수의 본문(body)에 JSX 문법을 사용하여 UI를 정의하고 있습니다. JSX 문법은 리액트에서 UI를 구성하는 간편한 방법으로, HTML과 유사한 형태로 작성할 수 있습니다. 이 경우 <div> 태그로 감싸진 "Contact" 텍스트를 반환하여 화면에 렌더링합니다.
- export default Contact; : Contact 컴포넌트를 외부에서 재사용할 수 있도록 내보내기(export) 설정을 하고 있습니다. 이렇게 다른 파일에서 해당 컴포넌트를 불러와 사용할 수 있습니다.
JSX(JavaScript XML)는 리액트(React)에서 사용되는 자바스크립트의 확장 문법으로, UI를 구성하기 위해 XML과 유사한 형태로 작성하는 것을 가능하게 해주는 문법입니다. JSX를 사용하면 리액트 컴포넌트의 렌더링을 더 직관적이고 가독성 좋게 작성할 수 있습니다. JSX는 리액트 컴포넌트의 중요한 특징 중 하나이며, 일반 자바스크립트 코드와 결합하여 사용됩니다. 즉 자바스크립트와 HTML을 같이 편하게 쓰기 위한 방법입니다.
- XML과 유사한 문법 : JSX는 XML과 비슷한 형태를 가지고 있으며, 태그와 속성 등을 사용하여 컴포넌트의 UI를 정의합니다.
- JSX 표현식 : JSX 내부에서는 중괄호({})를 사용하여 자바스크립트 표현식을 삽입할 수 있습니다. 이를 통해 동적으로 데이터를 렌더링하거나 연산을 수행할 수 있습니다.
- 컴포넌트 사용 : JSX에서는 컴포넌트를 직접 사용할 수 있습니다. 다른 컴포넌트를 JSX 내에서 태그 형태로 작성하여 해당 컴포넌트를 렌더링할 수 있습니다.
- 속성(Props) 사용 : JSX에서는 HTML 태그에 속성(attribute)을 추가하여 컴포넌트에 데이터를 전달할 수 있습니다. 이러한 데이터는 컴포넌트 내에서 props 객체로 접근할 수 있습니다.
- 닫는 태그 : 일반적인 HTML 태그와 마찬가지로 닫는 태그를 사용하여 요소를 닫아야 합니다. 하지만 빈 요소를 표현할 때는 XML에서 사용하는 방식과 같이 /를 사용하여 닫는 태그를 생략할 수 있습니다.
Footer.js
파일에는 다음과 같이 기본 소스만 넣어주겠습니다.
주의 할 점이 컴퍼넌트를 만들 때에는 첫 글자를 대문자로 설정하는 것이 규칙입니다.
import React from "react";
const Footer = () => {
return <div>Footer</div>;
};
export default Footer;
Header.js
파일에는 다음과 같이 기본 소스만 넣어주겠습니다.
import React from "react";
const Header = () => {
return <div>Header</div>;
};
export default Header;
Intro.js
파일에는 다음과 같이 기본 소스만 넣어주겠습니다.
import React from "react";
const Intro = () => {
return <div>Intro</div>;
};
export default Intro;
Port.js
파일에는 다음과 같이 기본 소스만 넣어주겠습니다.
import React from "react";
const Port = () => {
return <div>Port</div>;
};
export default Port;
Site.js
파일에는 다음과 같이 기본 소스만 넣어주겠습니다.
import React from "react";
const Site = () => {
return <div>Site</div>;
};
export default Site;
Skill.js
파일에는 다음과 같이 기본 소스만 넣어주겠습니다.
import React from "react";
const Skill = () => {
return <div>Skill</div>;
};
export default Skill;
Skip.js
파일에는 다음과 같이 기본 소스만 넣어주겠습니다.
import React from "react";
const Skip = () => {
return <div>Skip</div>;
};
export default Skip;
Main.js
파일에는 다음과 같이 작성합니다.
Main 컴포넌트는 자식 컴포넌트들을 렌더링하는 래퍼(wrapper) 역할을 합니다.
Main 컴포넌트는 children prop을 받아와서 해당 자식 컴포넌트들을 <main> 태그로 감싸서 반환합니다.
이로써 Main 컴포넌트를 사용하면 여러 개의 컴포넌트를 하나의 <main> 영역으로 묶을 수 있습니다.
여기까지 잘 따라 했다면 브라우저에는 각 섹션의 이름이 나오면 성공한 것입니다.
import React from "react";
const Main = ({ children }) => {
return (
<main id="main" role="main">
{children}
</main>
);
};
export default Main;
2_3. SCSS 설정하기
SCSS는 CSS의 확장 버전으로, CSS의 단점을 보완하고 개발자들에게 더 편리한 방식으로 스타일 시트를 작성할 수 있도록 도와주는 전처리기(preprocessor)입니다. SCSS는 SASS(Syntactically Awesome Style Sheets)라는 원래 버전의 상위집합(superset)으로, CSS와 거의 동일한 구문을 사용하면서도 추가적인 기능과 유용한 문법을 제공합니다.
- 변수(Variables) : $ 기호를 사용하여 변수를 선언하고, 변수를 이용하여 스타일 값을 저장하고 재사용할 수 있습니다. 이를 통해 스타일 시트를 유지보수하기 쉽고 가독성이 좋게 만들어 줍니다.
- 중첩(Nesting) : 스타일 규칙을 중첩하여 DOM 트리의 구조와 일치시킬 수 있습니다. 이를 통해 스타일 시트의 계층 구조를 명확하게 표현할 수 있으며, 중첩된 요소의 스타일을 쉽게 찾고 수정할 수 있습니다.
- 믹스인(Mixins) : @mixin 지시어를 사용하여 스타일 규칙들을 정의하고, @include 지시어를 사용하여 해당 믹스인을 적용할 수 있습니다. 이를 통해 스타일 규칙들을 재사용하거나, 여러 스타일 규칙들을 하나로 묶어 사용할 수 있습니다.
- 상속(Inheritance) : @extend 지시어를 사용하여 스타일 규칙을 상속할 수 있습니다. 이를 통해 비슷한 스타일들을 그룹화하고 관리할 수 있으며, 스타일 코드의 중복을 줄일 수 있습니다.
- 조건문(Conditionals) : @if, @else if, @else와 같은 조건문을 사용하여 특정 조건에 따라 다른 스타일 규칙을 적용할 수 있습니다.
- 반복문(Loops) : @for, @each, @while과 같은 반복문을 사용하여 스타일 규칙을 반복해서 생성할 수 있습니다.
이번에는 scss를 이용해서 작업해보겠습니다.
npm run sass
를 통해서 scss가 설치되어 있어야 합니다.
SCSS 파일을 설정하고 import 할 때 앞에 언더스코어(_)를 붙이는 것은 SCSS의 부분 파일 또는 믹스인 파일을 의미합니다.
이렇게 파일명 앞에 언더스코어를 붙이면 해당 파일이 부분 파일이거나 믹스인 파일임을 나타내고, 이러한 파일들은 별도로 컴파일되지 않고 다른 SCSS 파일에서 @import 지시어를 통해 불러올 수 있습니다.
- assets
- img
- scss
- section
- _contact.scss
- _footer.scss
- _header.scss
- _intro.scss
- _port.scss
- _site.scss
- _skill.scss
- setting
- _fonts.scss
- _mixin.scss
- _reset.scss
- _vars.scss
- style.css
- section
style.scss
을 설정하겠습니다.
CSS 코드를 모듈화하고, 스타일 시트를 섹션별로 분리하여 관리할 수 있습니다.
이는 코드의 가독성과 유지보수성을 높여주는 방법입니다
@charset "UTF-8";
// setting
@import "setting/fonts";
@import "setting/vars";
@import "setting/reset";
@import "setting/mixin";
// section
@import "section/header";
@import "section/intro";
@import "section/skill";
@import "section/site";
@import "section/port";
@import "section/contact";
@import "section/footer";
_fonts.scss
을 설정하겠습니다.
@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@100;200;300;400;500;600;700;800;900&display=swap");
@import url("https://websfont.github.io/nanumSquareNeo/nanumSquareNeo.css");
@import url("https://websfont.github.io/gmarket/gmarket.css");
.mont {
font-family: "Montserrat";
}
.nanum {
font-family: "nanumSquareNeo";
}
.gmarket {
font-family: "gmarket";
}
_vars.scss
을 설정하겠습니다.
:root {
--mainEng-font: "Montserrat";
--mainKor-font: "nanumSquareNeo";
--mainNum-font: "gmarket";
--mainBg-color: #f3ede8;
--subBg100: #cdc0b1;
--subBg200: #afa395;
--subBg300: #81887c;
--subBg400: #afa7a2;
--subBg500: #a6afa2;
--white: #fff;
--black: #000;
--black100: #2b2b2b;
--black200: #434343;
--black300: #686868;
--black400: #e0e0e0;
font-family: var(--mainEng-font), var(--mainKor-font);
font-size: 16px;
line-height: 1.5;
font-weight: 400;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
@media (max-width: 800px) {
font-size: 14px;
line-height: 1.4;
}
}
body {
background-color: var(--mainBg-color);
}
_reset.scss
을 설정하겠습니다.
// border-box 초기화
*,
*:before,
*:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
// 공백 초기화
body,
button,
dd,
dl,
dt,
fieldset,
form,
h1,
h2,
h3,
h4,
h5,
h6,
input,
legend,
li,
ol,
p,
select,
table,
td,
textarea,
th,
ul,
figure,
figcaption {
margin: 0;
padding: 0;
}
// 폰트 초기화
body,
button,
input,
select,
table,
textarea {
font-family: var(--mainEng-font), var(--mainKor-font), "Apple SD Gothic Neo", "Malgun Gothic", "맑은 고딕", helvetica, sans-serif;
}
// 링크 초기화
a,
a:hover,
a:focus {
color: inherit;
text-decoration: none;
}
// 스타일 초기화
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: normal;
}
ul {
list-style: none;
}
em,
address {
font-style: normal;
}
strong {
font-weight: normal;
}
img {
vertical-align: top;
width: 100%;
}
// 스킵메뉴
#skip a {
position: absolute;
left: 10px;
top: -92px;
z-index: 100000;
font-size: 1rem;
padding: 10px 30px;
color: var(--white);
background: var(--black);
}
#skip a:focus,
#skip a:active {
top: 10px;
}
_mixin.scss
을 설정하겠습니다.
@mixin을 사용하여 스타일 규칙들을 묶어 믹스인으로 만들면, 해당 믹스인을 다른 스타일 규칙에서 @include 지시어를 사용하여 쉽게 불러와서 재사용할 수 있습니다.
간단하게 자주 사용하는 규칙을 믹스인으로 만들겠습니다.
// 가운데 정렬
@mixin flex-center {
display: flex;
align-items: center;
justify-content: center;
}
// 양쪽 정렬
@mixin flex-between {
display: flex;
align-items: center;
justify-content: space-between;
}
// 중앙 정렬
@mixin position-center {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
// 상단 고정
@mixin position-fixed {
position: fixed;
left: 0;
top: 0;
width: 100%;
}
scss 설정도 완료가 되었습니다. 하지만 적용은 되지 않습니다.
index.js
에서 CSS를 연동하여야 합니다.
import "./assets/scss/style.scss";
이 코드를 추가해주세요!
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./assets/scss/style.scss";
...
3. 마무리
이제 모든 코딩 준비가 되었습니다. 그럼 깃에 올립시다.
git add .
git commit -m "🥳 컴퍼넌트완료"
git push -u origin main
처음 배우는 개념들이 있으면 혼란스러울 수 있습니다. 하지만 몇 번 따라하면서 익히면 재미가 있습니다. 포기하지 말고 끝까지 잘 따라해주시면 감사하겠습니다. 그럼 이번 리액트도 끝까지 완성해봅시다.!
예제 목록
- 1. 포트폴리오 사이트 만들기 : Vite-Site : 셋팅하기
- 2. 포트폴리오 사이트 만들기 : Vite-Site : 레이아웃 설정
- 3. 포트폴리오 사이트 만들기 : Vite-Site : 헤더 영역
- 4. 포트폴리오 사이트 만들기 : Vite-Site : 인트로 영역
- 5. 포트폴리오 사이트 만들기 : Vite-Site : 스킬 영역
- 6. 포트폴리오 사이트 만들기 : Vite-Site : 사이트 영역
- 7. 포트폴리오 사이트 만들기 : Vite-Site : 포트폴리오 영역
- 8. 포트폴리오 사이트 만들기 : Vite-Site : 연락처 영역
- 9. 포트폴리오 사이트 만들기 : Vite-Site : 푸터 영역
- 10. 포트폴리오 사이트 만들기 : Vite-Site : 마무리
- 11. 포트폴리오 사이트 만들기 : React-Site : 셋팅하기
- 12. 포트폴리오 사이트 만들기 : React-Site : 컨퍼넌트 설정
- 13. 포트폴리오 사이트 만들기 : React-Site : 헤더 영역
- 14. 포트폴리오 사이트 만들기 : React-Site : 인트로 영역
- 15. 포트폴리오 사이트 만들기 : React-Site : 스킬 영역
- 16. 포트폴리오 사이트 만들기 : React-Site : 사이트 영역
- 17. 포트폴리오 사이트 만들기 : React-Site : 포트폴리오 영역
- 18. 포트폴리오 사이트 만들기 : React-Site : 연락처 영역
- 19. 포트폴리오 사이트 만들기 : React-Site : 푸터 영역
- 20. 포트폴리오 사이트 만들기 : React-Site : 마무리
- 21. 포트폴리오 사이트 만들기 : Vue-Site : 셋팅하기
- 22. 포트폴리오 사이트 만들기 : Vue-Site : 컨퍼넌트 설정
- 23. 포트폴리오 사이트 만들기 : Vue-Site : 헤더 영역
- 24. 포트폴리오 사이트 만들기 : Vue-Site : 인트로 영역
- 25. 포트폴리오 사이트 만들기 : Vue-Site : 스킬 영역
- 26. 포트폴리오 사이트 만들기 : Vue-Site : 사이트 영역
- 27. 포트폴리오 사이트 만들기 : Vue-Site : 포트폴리오 영역
- 28. 포트폴리오 사이트 만들기 : Vue-Site : 연락처 영역
- 29. 포트폴리오 사이트 만들기 : Vue-Site : 푸터 영역
- 30. 포트폴리오 사이트 만들기 : Vue-Site : 마무리
- 31. 포트폴리오 사이트 만들기 : Next-Site : 셋팅하기
- 32. 포트폴리오 사이트 만들기 : Next-Site : 컨퍼넌트 설정
- 33. 포트폴리오 사이트 만들기 : Next-Site : 헤더 영역
- 34. 포트폴리오 사이트 만들기 : Next-Site : 인트로 영역
- 35. 포트폴리오 사이트 만들기 : Next-Site : 스킬 영역
- 36. 포트폴리오 사이트 만들기 : Next-Site : 사이트 영역
- 37. 포트폴리오 사이트 만들기 : Next-Site : 포트폴리오 영역
- 38. 포트폴리오 사이트 만들기 : Next-Site : 연락처 영역
- 39. 포트폴리오 사이트 만들기 : Next-Site : 푸터 영역
- 40. 포트폴리오 사이트 만들기 : Next-Site : 마무리
댓글