React 설치 및 프로젝트 생성
node.js 설치
안정적인 왼쪽의 LTS버전을 설치한다. React설치를 위한 npm 은 node.js 설치 시 함께 설치된다.
프로젝트용 폴더 생성
프로젝트용 폴더를 생성하고, 우클릭을 통해 터미널로 폴더를 연다.
터미널에서 npx create-react-app 프로젝트명 을 입력하고 Enter를 치면 폴더 안에 프로젝트명으로 된 폴더가 생성된다.
(mac 기준 오류 발생 시 sudo npx create-react-app 프로젝트명 입력 후 Enter를 치고 비밀번호를 입력하면 된다.)
npx create-react-app 프로젝트명
폴더별 역할
코드 에디터로 생성된 프로젝트 폴더를 열면 아래 사진과 같이 폴더와 파일들이 생성된다.
node_modules
프로젝트 구동에 필요한 모든 라이브러리 코드를 보관. 깃허브에 업로드되지 않는다.
public
html/image 등 static 파일을 보관
src
css/js 등 메인 소스코드를 보관
package.json
프로젝트정보가 객체형식으로 정리되어있는 파일
- "dependencies": { js 라이브러리들이 설치된 정보들 }
- "scripts": { 리액트 명령어들 }
.gitignore
깃허브 업로드 시 제외 될 항목들을 저장 한 파일
메인이 되는 파일
src폴더의 app.js 파일이 내가 작성해야하는 파일이다.
간단한 구동 방식은 app.js 의 app() 함수 안의 html내용 들이 index.js 를 통해 index.html에 적용되는 방식이다.
라이브로 미리보기 하는 법
새 터미널을 열어 npm start 를 입력하고 엔터치면 html의 라이브서버처럼 실시간으로 반영되는 모습을 볼수 있다.
간단한 기본 문법
React환경에서 태그 자동완성 적용하려면 setting.json에 아래 코드 추가할 것
"emmet.includeLanguages": { "javascript": "javascriptreact" },
jsx syntax
React는 app.js 파일 내의 app() 함수 내에 html코드를 작성해서 페이지를 제작한다.
하지만 사실 이 코드는 html코드가 아니라 jsx라는 코드다.
html과 비슷하지만 JavaScript코드도 동시에 사용할 수 있는 것이 특징이다.
그래서 일반적으로 태그 내에 클래스 와 스타일 을 넣을 때 일반 HTML과는 조금 다르다.
HTML에서의 클래스와 스타일 작성법
<!-- 클래스 -->
<div class="test"></div>
<!-- 스타일 -->
<div style="display:block;"></div>
React(jsx)에서의 클래스와 스타일 작성법
<!-- 클래스 -->
<div className="test"></div>
<!-- 스타일 -->
<div style={{display:block;}}></div>
클래스의 경우 JavaScript의 class문법이 따로 있기 때문에 위와 같이 클래스는 class가 아닌 className으로 작성해야하고, 스타일은 중괄호 두개 로 묶어 작성해야한다.
스타일 작성 시 background-size / font-size 등 중간에 - 기호가 붙은 프로퍼티들은 - 가 산술연산자 로 받아들여 프로퍼티에 오류가 발생한다.
이 때, backgroundSize / fontSize 처럼 뒷 단어를 - 없이 붙이고 첫 글자를 대문자 로 바꾸는 카멜기법 을 사용한다.
그리고 jsx는 같은 태그를 병렬 기입 할 수 없다.
<div></div> // 이미 생성됨
<div></div> // 병렬 기입 불가능
이럴 때에는 두개의 태그를 다시 한 번 <div> 태그로 묶어줘야 하는데 이럴때 div보다는 <></> 와 같이 Fragment태그로 감싸면 된다.
변수(데이터) 바인딩
태그 안에 미리 미리 선언된 변수(데이터 / 자료 등) 을 넣을 때에는 중괄호 { 변수명 }를 사용해서 넣으면 된다. 이를 데이터 바인딩 이라고 한다.
let logo = 'Hello, World!';
<h4>{logo}</h4>
State 문법
일반적인 변수는 변경 시 html을 수정해줘야 페이지에 반영이 된다.
State 의 변수는 값을 변경해줘도 html에서 자동으로 재렌더링 하여 바로 반영된다.
자주 변경될 것 같은 데이터들을 State로 만들어놓고 데이터 바인딩 을 사용한다.
let [a, b] = useState('var');
// a= 변수값 저장('var')
// b= State의 변경을 도와주는 함수
이를 destructuring(구조분해할당) 이라 부르는데 배열식으로 값을 넣으면 각 인덱스 번호에 맞는 값들이 변수에 지정되는 방식이다.
let [c, d] = [1, 2];
// c = 1
// d = 2
그래서 State도 배열형식으로 생성 할 수 있다. 생성해서 인덱스 번호로 값을 가져와도 된다.
let [test, setTest] = useState(['a', 'b', 'c']);
// title[0] = 'a'
// title[1] = 'b'
// title[2] = 'c'
태그 내의 이벤트로 상호작용하기
태그 안에 onClick같은 이벤트를 넣어 사용자와 상호작용이 가능하다. 이때 onClick 안의 내용에는 반드시 콜백함수가 와야한다.
function Func(){
JavaScript Code
}
<div onClick={Func()}></div>
화살표함수로 즉시 JavaScript코드를 사용 할 수도 있다.
<div onClick={()=>{JScode}></div>
State 변경 방법
State를 변경할 때에는 = 같은 대입연산자를 사용하면 안된다.
//NG
<div onClick={()=>{vari = 'bar'}></div>
State를 변경할 때에는 반드시 State변경 함수를 사용해야한다.
let [vari, changeVar] = useState('var');
// vari= 변수값 저장('var')
// changeVar= State의 변경을 도와주는 함수
//OK
let bar = 'bar'
<div onClick={()=>{changeVar(bar)}></div>
useState로 선언한 변수에 배열이나 객체가 있으면 변수를 복사하거나 수정해도 값이 변경되지 않는다.
변수는 기존 State와 변경된 State를 동시에 가르키고 있기 때문에 같다고 판단하는 것이다.
따라서 반드시 원본을 보존하고 스프레드문법([...])을 사용해서 사본배열을 만드는 것이 좋다.
let [vari, changeVar] = useState(['foo','bar']);
<div onClick={() => {
let copy = [...vari];
copy[0] = 'poo';
changeVar(copy); // 사본 State copy에 ['poo','bar']가 선언됨
}}>
</div>
컴포넌트(Component)
길고 복잡한 html코드들을 자주 사용해야 할 경우 컴포넌트에 축약해서 만들어 놓고 필요 시에 불러와 적용하는 방법이 있다.
컴포넌트 생성
컴포넌트의 이름을 가진 함수를 생성한다. (함수명은 컴포넌트라는 것을 알기위해 첫 글자를 대문자로 시작한다.)
function Modal(){
return()
}
함수 내 return값 에 코드를 작성한다.
function Modal() {
return (
<div className='modal'>
<h4>SubTitle</h4>
<p>Date</p>
<p>Info</p>
</div>
);
컴포넌트 생성 시 const로 화살표함수 생성해서 컴포넌트를 만들면 상수를 변경하지 못하는 특징때문에 컴포넌트의 변경을 막을 수 있다는 장점이 있다.
컴포넌트 사용
사용하고자 하는 위치에서 함수명의 태그를 불러와 사용한다.
// 기본 사용법
<Modal></Modal>
// 축약 사용법
</Modal>