Search

React 정리

해당 정리 내용은 아래 강의를 수강 후 개인적으로 정리한 내용입니다! 예시 내용과 주제 정리 순서 등 많은 부분이 다르니 정신건강을 위해 이해가 훨씬 잘되는 실제 강의를 수강하는것을 권장드립니다!
목차

React 란?

리엑트(React)는 자바스크립트를 사용하는 웹 프레임워크 중 하나이며, 웹앱을 만들 때 많이 사용된다고 한다.

Node 설치

리엑트를 사용하기 위해서는 먼저 Node.js 를 설치해야한다.
리엑트는 Node.js 설치 시 같이 설치되는 npx 명령어를 사용하여 프로젝트를 만들기 때문에, 별도의 명령어로 추가 설치가 필요없다.
Mac에서 brew를 사용한 설치법
# node 설치 brew install node # yarn 설치 brew install yarn
Bash
복사
설치가 완료되었다면, 아래 명령어로 Node의 버전을 확인하여 정상 설치를 확인한다.
# node 버전 확인 # v16.8.0 node -v
Bash
복사

React 프로젝트 생성

리엑트 프로젝트는 아래 명령어로 빠르게 생성이 가능하다.
아래 명령어로 프로젝트 생성 시, 명령어 실행위치에 프로젝트가 생성된다. 따라서, cd 명령어로 프로젝트 생성 위치로 이동 후 실행하자.
# 현재 위치에 test 라는 리엑트 프로젝트 생성 npx create-react-app test
Bash
복사
프로젝트가 생성되었다면, 해당 프로젝트 경로(ex: /test)로 터미널을 이동 후 npm 명령어를 사용하여 정상적으로 생성되었는지 확인할 수 있다.
# 로컬의 3000번 포트를 사용하여 실행 npm start
Bash
복사

React 프로젝트 구조

리엑트 프로젝트의 구조는 그리 복잡하진 않다.
/test ├── README.md ├── node_modules [폴더] ├── package-lock.json ├── package.json ├── public [폴더] └── src [폴더]
Bash
복사
node_modules : npm으로 설치한 패키지와 기본적으로 설치된 패키지가 존재한다.
package-lock.json, package.json : npm 으로 설치한 패키지의 정보가 작성된 파일이다.
public : 리엑트는 가상 DOM을 사용한다. 이때 필요한 html 파일등이 들어간 폴더이다.
src : 실제 개발시 작성한 코드가 저장되는 위치

React 문법 정리

필자는 Vue.js만 겉핥기만 해보고 프론트를 제대로 하는건 React가 처음이라 정리해두었다.
또한 React는 HTML 을 사용하는게 아니고(거의 비슷해보이지만), JSX라는 문법을 사용하기 때문에 정리가 필요하다고 생각하였다.

기본 작성 법

React는 class 라 부르지 않고, className 이라 부른다.
function App(){ return ( <div className="App"> <div className="title"> <div>React 공부</div> </div> </div> ) }
JavaScript
복사
리엑트는 중괄호{} 를 사용하여 변수명을 쉽게 원하는 위치에 넣어줄 수 있다.
js를 사용하면 document.getElementById().innerHTML 를 사용해야 하지만, 리엑트는 그러지 않아도 된다.
함수, 스타일 등 대부분 넣을 수 있는건 전부 가능하다. 하지만 inline style은 리엑트 공식 문서도 그닥 추천하지 않기 때문에, 그냥 CSS를 쓰는게 좋을거 같다.
var title = "React 공부"; function App(){ return ( <div className="App"> <div className="title"> <div>{ title }</div> </div> </div> ) }
JavaScript
복사

데이터를 다루는 법

리엑트에서는 var, let 등을 사용하여 값을 저장해도 되지만 state 라는 방법을 사용하여 값을 저장할 수 있다.

state와 일반 변수의 차이점?

state를 사용하는 이유는 일반 변수와 달리 "값이 변경되면 자동으로 변경된 데이터가 설정된 HTML을 렌더링 해준다." 이다.
즉, 일반 변수의 변경된 값이 적용된 사이트를 보기 위해서는 새로고침 이 필요하지만 state 를 사용하면 그럴 필요가 없다는 것이다!
그래서 state 방식을 사용한 값 저장은 자주 변경되는 데이터(제목 등)를 저장할 때 사용된다.

state 생성

useState 함수를 사용하여 state를 생성해준다. 이떄 생성되는 반환되는 데이터가 2개인데, 아래와 같다.
또한 useState 함수의 인자로 초기값을 설정할 수 있으며, 자료형 대부분이 가능하다.
실제 저장할 데이터
해당 데이터를 변경시킬 수 있는 함수
state 값은 직접 변경이 불가능하며, 반드시 변경을 시킬 수 있는 함수를 사용하여 데이터를 변경해야한다.
import React, { useState } from 'react'; import './App.css'; function App() { // 2개 값을 동시에 저장 let [title, setTitle] = useState('초기 제목 값') return ( <div className="App"> <div className="title"> <div>{ title }</div> </div> </div> ); } export default App;
JavaScript
복사
코드 실행
useState를 사용하여 생성한 state의 초기 값이 정상적으로 출력되는 것을 확인할 수 있다.

state 수정

위 과정에서 state를 만들었다면, 같이 생성된 수정 함수를 사용하여 데이터를 수정할 수 있다.
간단하게 버튼을 클릭하면 값이 변경되는 방법을 사용하였다.
import { useState } from 'react'; import './App.css'; function App() { let [title, setTitle] = useState('초기 제목 값') return ( <div className="App"> <div className="title"> <div>{ title }</div> <button onClick={()=>{setTitle('클릭 후 변경되는 제목 값')}}>제목 변경 버튼</button> </div> </div> ); } export default App;
JavaScript
복사
코드 실행
버튼 클릭 시, 제목이 초기 제목 값클릭 후 변경되는 제목 값 으로 변경되는 것을 확인할 수 있다.
제목을 바꾸는 버튼을 자세히 살펴보자.
일반적인 JS에서 사용하는 addEventListener() 를 사용하여 했던 작업이지만 훨씬 간단하다.
<button onClick={()=>{setTitle('클릭 후 변경되는 제목 값')}}>제목 변경 버튼</button>
JavaScript
복사
onClick : 클릭하였을 때 (합성 이벤트)
더 많은 이벤트의 정보는 React 공식문서를 참조
()=>{} : 콜백 함수 사용 (ES6 신버전 문법)
onClick={function(){~~}} 과 같다.
별도의 함수를 사용하여 넣어도 된다. 하지만 반드시 이름만 넣어야한다. (무한 실행의 원인이 된다.) onClick={()=>{ changeTitle } onClick={()=>{ changeTitle() }
setTitle('클릭 후 변경되는 제목 값') : state 선언 시 같이 선언된 변경함수를 사용하여 데이터 변경
변경 함수를 사용하여 데이터를 변경하면, 해당 데이터는 변경함수의 인자로 작성된 데이터로 완전히 대체된다. 즉, 변경될 값만 설정이 가능하며 기존 state의 변수명을 사용한 값은 안된다. 이런건 안된다 → setTitle( title + 1 )

state 수정 [응용]

만약 하나의 값이 아닌 배열이 state에 설정되어 있을 때는 수정을 어떻게 해야 될까?
state 변경함수에 대한 해당 설명에 state 변경함수에는 해당 state의 설정될 데이터를 직접 넣어줘야한다고 했다. 즉 아래 코드처럼 직접 데이터를 넣어주는 방법만 가능하다.
import { useState } from 'react'; ... let [list, setlist] = useState(['목록1', '목록2', '목록3']) ... onClick={ ()=>{ setlist(['변경 목록1', '목록2', '목록3']) } }
JavaScript
복사
하지만, 매번 코드에 데이터를 하드코딩 할 수 없기 때문에 값을 변경해주는 함수를 만들어야한다.
하지만 이 방법도 한계가 존재한다. 바로 어떤 제목을 수정해야하는지 알아야한다.
이는 이후 사용되는 props 라는 기능을 사용하면 된다.
배열에 새로운 값을 추가할 때는 아래 2가지 방법으로 값을 추가할 수 있다. - array.push(data) : 배열 맨 뒤에 값을 추가한다. - array.unshift(data) : 배열 맨 앞에 값을 추가한다.
import { useState } from 'react'; function App() { function ChangeTitle() { var newArray = [...list]; newArray[0] = '변경 목록1'; setList( newArray ); } let [title, setList] = useState(['목록1', '목록2', '목록3']) ... return ( <div className="App"> <div className="title"> <div>{ list }</div> <button onClick={ ChangeTitle }>제목 변경 버튼</button> </div> </div> ); ... }
JavaScript
복사
코드 실행

컴포넌트를 사용하자

현재는 return 할 때, 페이지에 사용되는 코드를 모두 한번에 반환해준다.
이럴 때 컴포넌트를 사용해서 사이트의 특정기능을 컴포넌트 형태로 만들어 필요할 때 추가해주는 방법을 사용할 수 있다.
컴포넌트 선언 후, return 시 하나의 태그로 묶어서 반환해야 한다. 만약 이 부분이 맘에 들지 않는다면, <> </> 로 묶어서 반환해도 된다.
import { useState } from 'react'; function App() { ... return ( <div className="App"> <div className="title"> <div>{ list }</div> <button onClick={ ChangeTitle }>제목 변경 버튼</button> </div> <SubPage></SubPage> </div> ); } function SubPage() { return ( <> <div> This is Sub Page! </div> <div> HELLO WORLD! </div> </> ) } ... }
JavaScript
복사
코드 실행

리엑트의 조건문

리엑트는 조건문을 사용하여 특정 컴포넌트 / 코드가 보이도록 만들 수 있다.
하지만, 직접적으로 if - else 구문을 사용할 수 없고 삼항연산자를 사용해야한다.
삼항연산자란? 조건문 ? 조건이 참 일때 실행 코드 : 조건이 거짓일 때 실행 코드
클릭 시 flag값을 스위치처럼 계속 바꿔주는 함수를 설정하였다.
import { useState } from 'react'; function App() { ... let [flag, setflag] = useState(false) return ( <div className="App"> <div className="title"> <button onClick={ ()=>{ setflag(!flag) } }>컴포넌트 스위치</button> </div> { flag ? <SubPage></SubPage> : null } </div> ); } function SubPage() { return ( <> <div> This is Sub Page! </div> <div> HELLO WORLD! </div> </> ) } ... }
JavaScript
복사
만약 아무 코드를 실행하고 싶지 않을 때는 null 을 작성한다.
코드 실행
버튼을 클릭하면 컴포넌트(SubPage)를 스위치처럼 표시 / 미표시 상태로 만들 수 있다.

리엑트의 반복문 [map 함수 사용]

리엑트는 반복문을 사용하여 반복되는 컴포넌트 / 코드가 보이도록 만들 수 있다.
하지만, 직접적으로 for 구문을 사용할 수 없고 map을 사용하거나 함수를 정의하여 사용해야한다.
import { useState } from 'react'; ... function App() { let [title_list, settitle] = useState(['제목1','제목2','제목3']) return ( <div className="App"> { title_list.map(function(e){ return( <div className="title"> TITLE : { e } / DETAIL : 내용 </div> ) }) } </div> ); } ...
JavaScript
복사
코드 실행
map 메서드를 사용할 때 인자를 사용하면 더 편리하게 반복을 사용할 수 있다.
map 메서드는 넣어주는 인자의 순서에 따라 기능이 다르다.
배열.map((요소, 인덱스, 배열) => { return 요소 });
첫번째 인자 : 각 배열의 아이템의 데이터를 저장
두번째 인자 : 각 배열의 인덱스
세번째 인자 : 해당 배열 값
즉 반복문의 인자를 사용하면 위 map 반복문을 아래처럼 설정할 수 있다.
각 제목의 ID(index)는 두번째 인자인 i , 제목의 데이터 값은 첫 번째인자인 e 를 사용한다.
{ title_list.map(function(e,i){ return( <div className="title"> ID : {i} / TITLE : { e } </div> ) }) }
JavaScript
복사
정적인 문자열에 동적인 변수 설정
만약 이미지 주소와 같이 기존 문자열의 일부 문자열을 반복되는 문자로 변경하고 싶을 땐, 해당 문자열 전체를 중괄호{} 로 묶은 후 사용한다.
/* 만약 props로 넘어온 index 값의 연산이 필요하다면 아래와 같이 연산하여 사용 */ /* https://mysite.com/img/example1.jpg */ /* https://mysite.com/img/example2.jpg */ ... <img src={ 'https://mysite.com/img/example'+ (props.index + 1) +'.jpg' } width="100%" />
JavaScript
복사

리엑트의 반복문 [함수를 정의하여 사용]

위 과정에서는 map 함수를 사용하여 반복문을 설정했다면, 아래 방법은 별도의 함수를 만들어 그 함수를 실행하는 방식이다.
import { useState } from 'react'; ... function App() { let [title_list, settitle] = useState(['제목1','제목2','제목3']) function UI() { var ui_array = []; for(let i=0; i<3; i++){ ui_array.push( <div className="title"> TITLE : { title_list[i] } / DETAIL : 내용 </div> ) } return ui_array } return ( <div className="App"> { UI() } </div> ); } ...
JavaScript
복사
코드 실행

props를 사용한 데이터 공유

우리가 컴포넌트안에 정의한 state는 해당 컴포넌트에서만 사용이 가능하다.
만약 특정 동작을 수행하는 자식 컴포넌트에서 부모 컴포넌트의 값이 필요할 때 props를 사용하여 값을 전달 / 사용할 수 있다.
값을 전달받기를 원하는 자식 컴포넌트의 함수 정의 부분에 props 인자를 추가한 후 사용할 수 있다.
클릭한 제목이 어떤 제목인지 확인할 수 있는 예시를 작성해보았다.
import { useState } from 'react'; ... function App() { let [title_list, settitle] = useState(['제목1','제목2','제목3']) let [clickidx, setidx] = useState(0) function UI() { var ui_array = []; for(let i=0; i<3; i++){ ui_array.push( // 제목 클릭 시 clickidx값 설정 <div className="title" onClick={ ()=>{ setidx(i) } }> TITLE : { title_list[i] } / DETAIL : 내용 </div> ) } return ui_array } return ( <div> <div className="App"> { UI() } </div> <Sub title_list={title_list} clickidx={clickidx}/> </div> ); } function Sub(props) { return ( <div className="Sub"> <div> <h2>내가 클릭한 제목 : { props.title_list[props.clickidx] }</h2> </div> </div> ) } ...
JavaScript
복사
Sub 컴포넌트에 사용된 Css는 아래와 같다.
.Sub{ margin-top: 20px; padding: 20px; background: #eee; }
CSS
복사
부모 컴포넌트(App)에서 아래 코드로 props를 전달해준다.
... // title_list, clickidx 이름으로 값 전달( 중괄호{} 사용 ) <Sub title_list={title_list} clickidx={clickidx}/> ...
JavaScript
복사
자식 컴포넌트(Sub)에서 아래와 같이 사용한다.
... // props.전달받은이름 형식으로 사용 <h2>내가 클릭한 제목 : { props.title_list[props.clickidx] }</h2> ...
JavaScript
복사
코드 실행
내가 클릭한 제목이 아래 자식 컴포넌트(Sub)에 표시된다.

여러 데이터에서 원하는 요소 찾기

만약 부모 컴포넌트에서 props를 사용하여 데이터를 얻었지만, 원하는 요소 일부만 필요할 경우 사용할 수 있는 방법이다.
바로 반복되는 객체에 find() 를 사용하는 것이다. 사용법은 map 함수와 동일하다.
function TEST(props){ // 원하는 조건에 맞는 요소만 찾아준다. let detail = props.alldata.find((e)=>{return 조건} ... }
JavaScript
복사

입력창에 입력한 값을 사용하는법

input 태그 같은 곳에 입력한 값을 확인하기 위해서는 아래 코드를 사용한다.
... let [input, setinput] = useState(); ... return ( <div> <div className="App"> 입력 값 : { input } <div> <input onChange={ (e)=>{ setinput(e.target.value) } } /> </div> </div> </div> ); ...
JavaScript
복사
onChange : 해당 태그의 입력한 값이 변경될 때 실행
(e)=>{ setinput(e.target.value) } : 콜백함수 첫 번째 인자를 이용하여 이벤트 객체로 참조
이후 setinput 함수에는 기존 자바스크립트와 동일하게 event.target.value 문법을 사용하여 값을 얻는다.
코드 실행
input창에 값을 입력하면 상단에 입력한 값이 실시간으로 같이 변경되며 표시된다.
이를 이용하여 값을 입력할 때마다 실시간으로 ID / 닉네임을 확인하는 기능을 만들 수 있을거 같다.

export & import를 사용하여 외부에서 데이터 가져오기

리엑트 프로젝트를 만들면서, 하나의 js 파일에 동작에 필요한 모든 데이터를 저장한다면 코드와 데이터 관리가 매우 불편해진다.
따라서 다른 파일에 데이터를 저장한 후, import하여 사용한다면 데이터와 코드 관리가 편해진다.
순서는 아래와 같다.
1.
다른 js파일에 필요한 데이터를 작성한다.
2.
데이터를 작성한 js파일에서 데이터를 export한다.
3.
데이터가 작성된 js 파일을 import하여 사용한다.

export로 데이터를 외부와 공유하기

export 도 2가지 방식으로 사용될 수 있다.
1.
export [ 변수 ]
이 방법으로 데이터를 export 하게 된다면 import 때는 export 와 동일한 변수명을 사용해야한다.
export 코드 (data.js)
var data = [ { id : 0, name : "name1", age : 13 }, { id : 1, name : "name2", age : 15 }, { id : 2, name : "name3", age : 20 }, ] export default data
JavaScript
복사
import 코드 (App.js)
import하는 파일이 js 파일일 경우 js 파일 확장자를 표시하지 않아도 된다.
//import { data } from './data' 도 가능 import userdata from './data.js'; ... <div> { userdata[0] } </div> ...
JavaScript
복사
2.
export default [ 변수 or 값 ]
이 방법으로 데이터를 export 하게 된다면 import 때는 변수명을 마음대로 사용해도 된다.
단, export default 는 한번만 사용가능하다.
export 시 변수명을 지정하지 않을 경우 기본값으로 export될 데이터를 설정하는 옵션이기 때문이다.
즉, 해당 js 파일의 대표 export 값 이라고 생각하면 된다.
export 코드 (data.js)
var data = [ { id : 0, name : "name1", age : 13 }, { id : 1, name : "name2", age : 15 }, { id : 2, name : "name3", age : 20 }, ] export default data
JavaScript
복사
import 코드 (App.js)
import하는 파일이 js 파일일 경우 js 파일 확장자를 표시하지 않아도 된다.
//import { data } from './data' 도 가능 import userdata from './data.js'; ... <div> { userdata[0] } </div> ...
JavaScript
복사

Router를 활용한 페이지 설정

우리가 만드는 모든 기능을 하나의 url에 적을 수는 없다.
특정 url에 접속하였을 때는 이전 페이지와는 다른 기능을 보여줄 수 도 있기 때문이다.

react-router-dom 설치

npm install react-router-dom
Bash
복사

Router 설정

설치가 완료되었다면, html 파일로 만들 때 사용되는 메인 js 파일(기본은 index.js)에 아래 태그를 추가한다.
태그는 아래 2가지 태그 중 선택하여 사용한다.
<BrowserRouter></BrowserRouter>
<HashRouter></HashRouter>
동적인 데이터를 다루기 때문에 본인은 BrowserRouter를 사용하였다.
사용을 위해선 이전에 설치한 react-router-dom 에서 BrowserRouter를 import 해야한다. (HashRouter도 마찬가지다.)
... import { BrowserRouter } from 'react-router-dom' ReactDOM.render( <React.StrictMode> <BrowserRouter> <App /> </BrowserRouter> </React.StrictMode>, document.getElementById('root') ); ...
JavaScript
복사

BrowserRouter vs HashRouter

BrowserRouter 특징
주소에 # 이 붙지 않는다.
서버에서 요청한 데이터를 가공 후 보여주는 동적인 페이지에 적합하다.
새로고침을 하면 경로를 찾지 못하는 경우가 있다. (동적인 페이지에 필요한 데이터 없이 접속하기 때문)
HashRouter 특징
주소에 # 이 붙는다.
미리 저장된 데이터를 보여주는 정적인 페이지에 적합하다.
새로고침을 해도 잘 접속된다.
검색엔진에 잡히지 않는다.
내용 출처

각 페이지 URL 설정

<Route> 태그 사용법

이제 컴포넌트가 작성된 js파일에서 <Route></Route> 태그를 사용하여 url을 설정할 수 있다.
<Route></Route> 태그로 URL을 설정하면 기본적으로 path 에 매칭되는 모든 경우를 표시해준다. 따라서 exact 를 추가해주면 중복되어 매칭되는 것을 방지해준다. 또는 <Route> 태그 전체를 하나의 <Switch> 태그로 감싸주면 중복없이 가장 먼저 매칭된 Router를 사용한다.
import { Route } from 'react-router-dom' ... <Route exact path="/"> <div> 이 페이지는 메인페이지입니다! </div> </Route> <Route exact path="/detail"> <div> 이 페이지는 상세페이지입니다! </div> </Route> ...
JavaScript
복사
/ 경로로 접속 시
/detail 경로로 접속 시

<Route> 태그에서 파라미터 전달하기

<Route> 태그에서 : 문자를 같이 사용하면 url에 입력한 값을 컴포넌트에서 useParams 를 사용하여 얻어올 수 있다.
Router 정보를 설정한 js 파일
/detail/ 주소 뒤에 입력한 값을 id 라는 이름의 파라미터로 <Detail> 컴포넌트에 전달한다.
import { Route } from 'react-router-dom' ... <Route path="/detail/:id"> <Detail shoes={shoes}></Detail> </Route>
JavaScript
복사
해당 파라미터를 얻어와 사용하는 컴포넌트를 정의한 js 파일
import { useParams } from "react-router-dom"; ... function Detail(props){ let { id } = useParams(); ... }
JavaScript
복사

<Link> 태그 사용법

<Link></Link> 태그를 사용하여 클릭 시 원하는 주소로 이동하는 링크를 만든다.
import { Route, Link } from 'react-router-dom' ... <Route exact path="/"> <div> 이 페이지는 메인페이지입니다! </div> <div> <Link to="/detail1">상세페이지1</Link> </div> <div> <Link to="/detail2">상세페이지2</Link> </div> </Route> <Route exact path="/detail1"> <div> 이 페이지는 상세페이지1입니다! </div> </Route> <Route exact path="/detail2"> <div> 이 페이지는 상세페이지2입니다! </div> </Route> ...
JavaScript
복사

이전 페이지로 돌아가는 기능 만들기

useHistory 를 사용하여 이전 페이지로 이동하는 기능을 만들 수 있다.
import { useHistory } from 'react-router-dom' ... let history = useHistory(); ... <Route exact path="/"> <div> 이 페이지는 메인페이지입니다! </div> <div> <Link to="/detail">상세페이지</Link> </div> </Route> <Route exact path="/detail"> <div> 이 페이지는 상세페이지입니다! </div> <button onClick={ ()=>{history.goBack()} }>이전 화면으로 이동</button> </Route>
JavaScript
복사
코드 실행

컴포넌트 Lifecycle & Hook

컴포넌트의 생성 / 업데이트 / 삭제 등 컴포넌트에 변화가 생길 때 특정 동작을 실행시킬 수 있도록 만들 수 있다.
이때 useEffect 라는 것을 사용한다. 이는 react 에서 import 가능하다.
useEffect를 사용한 후킹 함수 정의는 한 컴포넌트에 여러개 정의가 가능하다. 단, 정의한 순서대로 동작하는 점은 유의해야한다.

컴포넌트 생성 시 Hook

컴포넌트 최초 생성 시 특정 동작을 수행할 때는 useEffect의 콜백 함수 안에 원하는 동작을 적어준다.
import React, {useState, useEffect} from 'react'; function Detail(){ useEffect(()=>{ ... 컴포넌트 최초생성 시 실행코드 작성 ... }); ... }
JavaScript
복사

컴포넌트 업데이트 시 Hook

컴포넌트 업데이트(재 렌더링)시에는 컴포넌트 생성 시 작성한 Hook 동작 코드가 실행된다.
하지만 컴포넌트가 재 렌더링 될때마다 컴포넌트 생성 동작을 진행시키면 곤란하기 때문에, 특정 조건에 맞는 재 렌더링이 발생하였을 때만 진행되도록 만들어야한다.
이 조건은 useEffect특정 state명을 이용해 설정할 수 있다.
재 렌더링 시, 조건으로 설정한 state가 변경되었을 때만 코드를 실행하도록 만드는것이다.
import React, {useState, useEffect} from 'react'; function Detail(){ let [data,setdata] = useState() useEffect(()=>{ ... 컴포넌트 최초생성(재 렌더링 시) 실행코드 작성 ... },[state 명, ...]); ... }
JavaScript
복사
하지만, 컴포넌트를 최초 실행할 때만 동작하고 싶은 동작을 설정하기 위해서는 재 렌더링시에는 무조건 실행되지 않는 코드를 작성해야한다.
이럴때는 state명을 입력하는 조건 부분을 빈 공간, 즉 [] 로 설정하면 된다.
import React, {useState, useEffect} from 'react'; function Detail(){ let [data,setdata] = useState() useEffect(()=>{ ... 컴포넌트 최초생성시에만 동작할 수 있는 실행코드 작성 ... },[]); ... }
JavaScript
복사

컴포넌트 삭제 시 Hook

컴포넌트 최초 생성 시 특정 동작을 수행할 때는 useEffect의 콜백 함수 안의 return 부분에 원하는 동작을 적어준다.
import React, {useState, useEffect} from 'react'; function Detail(){ useEffect(()=>{ return 컴포넌트 삭제 시 실행코드 작성 }); ... }
JavaScript
복사
만약 타이머(setTimeout)를 Hook 동작코드에 사용하였다면 컴포넌트 삭제 시 clearTimeout 함수로 타이머를 해제되도록 만들어야된다.
import React, {useState, useEffect} from 'react'; function Detail(){ useEffect(()=>{ // 5초 지연 후 코드를 동작하는 타이머를 생성 let mytimer = setTimeout(()=>{ ... 코드 ... }, 5000); // clearTimeout 함수로 타이머 해제 return ()=>{ clearTimeout(mytimer) } }, []); ... }
JavaScript
복사

리엑트 프로젝트 디자인

BootStrap & React-bootstrap

리엑트에서도 BootStrap을 활용한 디자인을 할 수 있다. (물론 다른 많은 UI 디자인 프레임워크도 많다.)
BootStrap을 활용하면 많은 양의 CSS 파일을 작성하지 않아도 되며, 간단한 프로젝트의 디자인은 웬만해선 커버가 가능하다.
리엑트에선 일반적은 BootStrap말고도 react-bootstrap 이 따로 존재한다.

react-bootstrap & bootstrap 설치

npm install react-bootstrap bootstrap
Bash
복사

html 코드에 react-bootstrap 참조 설정

버전이 보통 2가지 중 하나를 사용하는데, 버전마다 사용할 수 있는 기능이 다르기 때문에 확인 후 적용해야한다.
react-bootstrap 1.6.4v (Bootstrap 4)
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous" />
HTML
복사
react-bootstrap 2.0.0v (Bootstrap 5.1)
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous" />
HTML
복사

React-bootstrap 사용 예시

React-bootstrap의 여러 기능들의 사용법은 아래 주소를 확인하면된다.
일반 Bootstrap이 class(className)으로 구분하여 적용한다.
하지만, React-bootstrap사용할 컴포넌트를 React-bootstrap에서 import후 사용하는 방법으로 적용한다.
import { Navbar, ... } from 'react-bootstrap'; ... function App( <div className="App"> <Navbar bg="dark" variant="dark"> <Container> <Navbar.Brand href="#home"> TEST NAV </Navbar.Brand> </Container> </Navbar> ... </div> ) ...
JavaScript
복사
코드 실행
React-bootstrap에서 import한 Navbar 컴포넌트가 적용되었다.

styled-components

styled-components 라이브러리를 사용하면 내가 원하는 컴포넌트에 스타일을 미리 정의하여 만들 수 있다.
styled-components 설치
npm install styled-components
Bash
복사
`` 사이에 css 문법을 작성하여 정의하면 된다.
import styled from 'styled-components'; let mycomponent = styled.div` padding : 10px; color : blue; ` function main() { return ( ... <mycomponent></mycomponent> ... ) }
JavaScript
복사
styled-components 라이브러리에선 props 기능을 지원한다.
즉, 비슷한 css는 여러번 정의할 필요없이 props로 값을 입력받아 css를 변경하여 사용이 가능하다.
${ props => props.color }; 와 같이 콜백 함수 형태로 넣어줘야 한다.
import styled from 'styled-components'; let mycomponent = styled.div` padding : 10px; color : ${ props => props.color }; ` function main() { return ( ... <mycomponent color={'red'}>빨간색</mycomponent> <mycomponent color={'blue'}>파란색</mycomponent> ... ) }
JavaScript
복사

SCSS

CSS를 프로그래밍 언어처럼 작성할 수 있는 기능이다.
SCSS 문법을 사용하여 작성한 내용을 CSS로 컴파일해주기 때문이다.
SCSS 파일의 확장자는 *.scss 형태입니다.
SCSS 설치
npm install node-sass
Bash
복사

SCSS는 변수 사용이 가능하다!

scss 파일은 변수 사용이 가능하며, $변수명 : 값 형태로 사용한다.
물론 색상 뿐 아니라 css처럼 여러 값 모두 넣을 수 있다.
$maincolor : #ff0000; .red { color : $maincolor; }
Sass
복사

SCSS는 import가 가능하다!

다른 파일에 미리 css / sass 내용을 정의 후, import하여 사용하는 방법이다.
@import './mystyle.scss' ...
Sass
복사

SCSS는 같은 클래스의 CSS를 편리하게 정리할 수 있다!

만약 동일한 클래스로 여러 css를 작성할 경우 사용하는 방법이다.
이를 Nesting 문법이라고 한다.
기존 CSS 문법은 아래와 같이 작성한다.
div.container h4 { color : blue; } div.container p { color : green; }
CSS
복사
하지만 SCSS의 Nesting 문법을 사용하면 아래와 같이 동일한 class는 묶어 정의할 수 있기 때문에 관리가 수월하다.
div.container { h4 { color : blue; } p { color : green; } }
Sass
복사

SCSS는 기존에 정의한 스타일을 복붙(?) 할 수 있다!

@extend 문법을 사용하면 기존에 정의한 스타일을 붙여넣을 수 있다. 이를 사용하면 비슷한 스타일을 작성할 때 매우 유용하다.
.my-style { background : #ddeeee; width : 100%; } .new-style { @extend .my-style margin : auto; }
Sass
복사

SCSS는 스타일을 함수로 재사용 할 수 있다!

@mixin 으로 재사용할 스타일을 정의하고, @include 로 불러 사용한다.
@mixin mystyle() { background : #ffffee; max-width : 100px; width : 100%; margin : auto; } .copy { @include mystyle() }
Sass
복사

그 외 여러 내용들 (Error, Warning 등)

ERROR

리엑트를 사용하며 확인한 Error에 대한 내용을 작성하였다.

Warning

리넥트를 사용하며 확인한 Warning에 대한 내용을 작성하였다.

eslint 관련 warning

프로젝트 작성 후, npm start 등의 명령어로 실행하면 아래와 같은 esline 관련 경고가 출력될때가 있다.
esline가 기본 설정이 되어 있기 때문에, 사용하지 않은 함수나 변수 or 코딩 작성등을 훈수(?) 두는 것이다.
Compiled with warnings. src/App.js Line 6:15: 'setTitle' is assigned a value but never used no-unused-vars Search for the keywords to learn more about each warning. To ignore, add // eslint-disable-next-line to the line before.
JavaScript
복사
이 훈수(?)가 거슬리면 파일 최상단에 아래의 추석을 추가하면 된다.
/*eslint-disable*/
JavaScript
복사