React 사용 이유
1. Single Page Application (SPA) 만들 때 사용
- 새로고침 없이 앱처럼 부드럽게 동작하는 웹페이지
- html 파일을 한개만 사용하여 다른 페이지 보여주고 싶을 때 html 부분 다 갈아 치워서 보여줌
2. html 재사용 편리
- 변수에 html 담아서 사용할 수 있기 때문에
3. 같은 문법으로 앱 개발 가능 (React Native)
리액트 프로젝트 생성
1. 작업용 폴더 하나 생성
2. 터미널에서 해당 폴더 접근 후 npx create-react-app '프로젝트명' 입력
3. 해당 프로젝트 폴더 vscode 에서 열기
4. App.js 가 메인 페이지이므로 App.js 에서 코드 짜줌
5. 브라우저로 미리보기 띄우고 싶으면 터미널에 npm start 입력
App.js 가 코드 짜주는 메인 페이지이다.
React 초기 상태
import ...;
function App(){
return (
<div className="App">
</div>
)
}
위와 같은 상태에서 시작하면 깨끗한 백지 상태에서 시작할 수 있다.
우선 상단 nav bar 부터 생성
(App.js)
function App(){
return (
<div className="App">
<div className="black-nav">
<h4>블로그임</h4>
</div>
</div>
)
}
(App.css)
.black-nav {
background : black;
width : 100%;
display : flex;
color : white;
padding : 20px;
}
css 의 경우엔 App.css 파일 안에 작성해주면 된다.
JSX 문법
1. html 에 class 넣어줄 땐 className 사용
스타일을 주기 위해 class명을 넣을 때 class="" 가 아닌 className="" 을 사용한다.
React 이용하여 App.js 에서 코드 짜는 것은 html 이 아니라 JSX 이기 때문이다.
원래 리액트 환경에서 html 생성하려면 자바스크립트로 React.createElement('div', null) 와 같이 작성해주어야한다. 저렇게 작성하면 더 복잡하기 때문에 JSX 를 사용한다.
JSX 는 html 과 사용방식이 유사하다.
JSX 는 일종의 자바스크립트여서 자바스크립트에서 사용하는 예약어인 class 라는 키워드를 막 사용할 수 없다. 따라서 class="" 사용하고 싶으면 className="" 라고 사용해야한다.
2. 변수를 html에 삽입할 때는 {} 중괄호 사용
html 중간에 변수를 넣어주어야 하는 경우가 많이 생긴다. (데이터 바인딩)
자바스크립트에서는 해당 요소를 찾아서 document.getElementById().innerHTML = "" 과 같은 방식을 사용했다면, 리액트에서는 더욱 쉽게 데이터를 넣어줄 수 있다.
function App(){
let post = '맛집';
return (
<div className="App">
<div className="black-nav">
<div>Blog</div>
<div>{ post }</div>
</div>
</div>
)
}
위와같이 작성해주면 손쉽게 post 변수를 div 에 넣어줄 수 있다.
function App(){
var data = 'red';
return (
<div className="App">
<div className="black-nav">
<div>개발 blog</div>
<div className={data}>안녕하세요</div>
</div>
</div>
)
}
태그 사이뿐만 아니라 className 같은 모든 곳에 데이터를 삽입해줄 수 있다.
3. html 에 style 속성을 넣어줄 때
<div style="color: blue"> 과 같이 작성하고 싶을 때, JSX 에서는 style = {} 안에 {} 자료형으로 집어넣어야한다.
<div style={ {color : 'blue', fontSize : '30px'} }> 글씨 </div>
{속성명: "속성값"} 이런 식으로 넣어주면 된다.
font-size 처럼 속성명에 대쉬(-) 기호를 사용할 수 없으므로 대쉬 기호 없이 camelCase 로 작성 해주어야 한다. (fontSize)
State
리액트는 변수 말고 state 를 만들어서 데이터를 저장할 수 있다.
import logo from "./logo.svg";
import "./App.css";
import { useState } from "react";
function App() {
let post = "강남 맛집";
let [title, setTitle1] = useState([
"남자 코트 추천",
"강남 우동 맛집",
"파이썬 독학",
]);
let [logo, setLogo] = useState("ReactBlog");
return (
<div className="App">
<div className="black-nav">
<h4>{logo}</h4>
</div>
<div className="list">
<h4>{title[0]}</h4>
<p>2월 17일 발행</p>
</div>
<div className="list">
<h4>{title[1]}</h4>
<p>2월 17일 발행</p>
</div>
<div className="list">
<h4>{title[2]}</h4>
<p>2월 17일 발행</p>
</div>
</div>
);
}
useState 를 import 해준 후,
원하는 곳에 useState('자료') 쓰면 state 에 자료를 잠깐 저장할 수 있다.
저장한 자료를 나중에 사용하려면 let[a, b] = useState('자료');
a자리에 state 이름을 작명하고 사용하면 된다.
변수말고 state 에 데이터를 저장해서 사용하는 이유
state 는 변동사항이 생기면 state 를 사용하는 html 을 자동으로 재렌더링 해준다.
일반 변수에 저장하여 사용하면, 변수 내용이 바뀌었을 때 html 재렌더링 해달라고 코드를 짜주어야하지만, state 변수를 사용하면 자동으로 해주기 때문에 state 변수를 사용하는 것
장점
- UI 기능 개발이 편리
- SPA 사이트처럼 부드럽게 동작
잘 바뀌지 않는 데이터들은 굳이 state로 저장할 필요 없이 변수 사용해주어도 된다.
state 는 상품명, 글제목, 가격 처럼 자주 변할 것 같은 데이터들을 저장하는 것이 좋은 관습이다.
onClick 사용하기
<div onclick="~~"></div>
일반 html 에서는 위와 같이 사용하지만, JSX 에서는 다음과 같이 사용한다.
<div onClick={실행할 함수}></div>
1. camelCase 로 작성해주고
2. {} 중괄호 사용하고
3. 중괄호 안에 그냥 코드가 아니라 함수를 넣어주어야 함.
<div onClick={ function(){ 실행할코드 } }>
<div onClick={ () => { 실행할코드 } }>
위와같이 안에서 함수 만들어서 사용해도 된다.
state 변경하기
일반 변수는 변경할 때 변수 += 1 해주면 되지만 state는 그렇지 않다.
state 를 변경하려면 setState 함수를 사용하여 변경해야한다. (html 재렌더링 해줌)
let [title, setTitle] = setState(0)
<div onClick={()=> {
setTitle(title + 1)
}}>
위와같이 setTitle 함수 안에 새로 지정할 값을 넣어주어야 title 값이 변경된다.
정리
- 클릭 시 이벤트 실행하고 싶으면 onClick={함수} 이벤트 핸들러 달아서 사용
- state 변경 시, state 변경함수를 사용하여 변경
array / obect 자료형 state 에 담아서 사용할 때
state 변경함수 동작 원리
state 변경함수를 사용하면 기존 state 와 신규 state 를 먼저 같은 지 검사해준다.
검사 했을 때, 같다면 state 변경을 해주지 않는다.
array / object 자료형 동작원리
자바스크립트는 array 나 object 자료를 하나 만들면 데이터들은 램이라는 가상공간에 저장되고, 변수에느 자료가 저장된 주소만 저장이 된다. 따라서
let data1 = [1,2,3];
let data2 = data1;
data1의 자료를 data2에 복사해주면, 새로운 저장공간에 [1, 2, 3] 을 새로 저장하는 것이 아니라 data1 에 저장된 주소를 data2 에도 저장하는 것이다.
data1 과 data2 는 똑같은 값을 공유한다.
data1 의 값을 바꾸게 되면 data2도 자동으로 변경된다.
쉽게 말해서 data1이 가르키고 있는 화살표를 data2 에도 복사한 것
let copy = title;
copy = "여자 코트";
setTitle(copy);
위와같이 작성해도 컴퓨터는 copy 와 기존 title state 는 같다고 판단하기 때문에 state 변경을 해주지 않는다.
let copy = [...title];
copy[0] = '여자 코트';
setTitle(copy)
위와같이 작성해주어야 한다.
점 세개는 spread operator 라고 하는 문법인데
array 나 object 자료형 왼쪽에 붙일 수 있고, 괄호를 벗겨주세요 라는 뜻이다.
...[1,2,3] 이렇게 작성하면 1,2,3 이 된다 (괄호 벗기기용 연산자)
따라서 괄호를 없앴다가 다시 씌워주므로 copy 에는 새로운 주소의 배열이 저장되기 때문에 주소가 다른 완전 독립적인 array 복사본을 만들어줄 수 있다.
object 자료형도 마찬가지
그리고 독립적인 사본을 shallow copy 또는 deep copy 라고 한다.
html 코드 짤 때 유의점
return(
<div></div>
<div></div>
)
return 안에 두개의 html 태그를 나란히 적는 것은 안된다.
return () 내부에는 하나의 태그로 시작해서 하나의 태그로 끝나야한다.
return(
<div>
<div></div>
<div></div>
</div>
)
그래서 굳이 두 개의 태그를 나란히 적고 싶으면 위와같이 하나의 div 로 감싸주어야 한다.
의미없는 div 를 사용하기 싫다면 <></> 로 감싸주어도 된다.
이름 fragment 문법 이라고 한다.
Component 문법
리액트는 긴 HTML 을 묶어서 깔끔하게 넣어줄 수 있는 문법을 제공한다. 이름 Component 라고 한다.
function App (){
return (
<div>
(생략)
<Modal></Modal>
</div>
)
}
function Modal(){
return (
<div className="modal">
<h4>제목</h4>
<p>날짜</p>
<p>상세내용</p>
</div>
)
}
위와같이 모달창을 하나 만들고 싶을 때, <Modal/> 하나의 태그로 줄여서 사용할 수 있다.
1. function 이용하여 함수를 하나 만들고 작명한다.
2. 함수 안 return() 안에 축약하고자하는 HTML을 작성한다.
3. 원하는 곳에서 <함수명></함수명> 사용하면 축약한 HTML 이 등장한다.
이러한 방식으로 축약한 HTML 묶음을 Component 라고 한다.
Component 사용할 때 주의점
1. Component 작명할 땐 영어 대문자로 시작한다.
2. return() 안에 html 태그들이 평행하게 여러개 들어갈 수 없다.
3. function App(){} 내부에 만들면 안된다.
-> function App() 도 컴포넌트이기 때문에 컴포넌트 안에 컴포넌트를 또 만들진 않는다.
4. <component></component> 이렇게 사용해도 되고, <component/> 이렇게 사용해도 된다.
const Modal = () => {
return ( <div></div> )
}
arrow function 사용해도 된다.
Component 쓰면 좋은 경우
- 사이트에 반복해서 출현하는 HTML 들
- 내용이 자주 변경될 것 같은 HTML 부분 잘라서 Component 사용하면 좋음
- 다른 페이지 만들고 싶다면 그 페이지의 HTML 내용을 하나의 Component 로 만들면 좋음
- 다른 팀원과 협업할 때 웹페이지를 Component 단위로 나눠 작업 분배하기도 함
Component 단점
예를 들어, function Modal 안에서 title state 를 사용하고 싶어서 {title} 이렇게 작성해주면 다른 function 이기 때문에 App 함수 내의 state 를 사용할 수 없다.
이럴 땐 props 문법을 사용해 state 를 <Modal> 까지 전달해주어야 사용할 수 있다.
=> 꼭 필요한 곳만 Component 로 쪼개서 사용하기
리액트 동적인 UI 만드는 step
동적 UI 는 유저가 조작 시 형태가 바뀌는
모달창, 탭, 서브메튜, 툴팁, 경고문 등 UI 를 의미한다.
- HTML CSS 로 미리 UI 디자인을 해놓고
- UI의 현재 상태를 state 로 저장해두고
- state 에 따라서 UI가 어떻게 보일지 조건문 등으로 작성
모달창 만들기
let [modal, setModal] = useState(false);
모달창의 상태를 state 변수에 넣어준다
true 일 때 모달창이 보이게, false 일 때 보이지 않도록 코드를 짜주면 된다.
JSX 에선 if 조건문을 바로 사용할 수 없다.
하지만 if 조건문 대신 삼항 연산자를 사용할 수 있다.
따라서 삼항연산자 사용하여 코드 짜주면
let [modal, setModal] = useState(false);
...
{
{modal ? <Modal /> : null}
}
글 제목 눌렀을 때 모달창 껐다 켰다 하도록 하고싶으면 onClick 속성 이용하면 된다.
let [modal, setModal] = useState(false);
...
<h4
onClick={() => {
if (modal == true) {
setModal(false);
} else {
setModal(true);
}
}}>
{title[2]}
</h4>
...
{
{modal ? <Modal /> : null}
}
리액트에서 UI 만드는 과정을 비유하면 스위치와 전동 만드는 것이랑 비슷하다
- 전등 달고
- 스위치랑 연결하고
- 스위치 on off 누를 때마다 켰다 꺼지도록 만듬
그리고 나중에 스위치 조작만 하면 됨
스위치는 state, 전등은 <Modal/>
옛 자바스크립트로 UI 만드는 것과 약간 방식이 다르다.
쌩 자바스크립트는 html 을 조작해야했는데, 리액트 환경에선 html 을 직접 조작하지 않는다.
예전 방식에 익숙하다면 리액트 식으로 마인드 바꾸어야한다.
'FrontEnd > React' 카테고리의 다른 글
export / import (0) | 2023.02.17 |
---|---|
React 이미지 파일 사용하기 (0) | 2023.02.17 |
Class 이용하여 컴포넌트 생성하기 (0) | 2023.02.17 |
props (0) | 2023.02.17 |
map 함수 (0) | 2023.02.17 |