[ 3D Web : Front_React.js ] React 개념공부 1
: JSX & 컴포넌트 & prop & state
∇ React 개념 공부 1 : JSX & 컴포넌트 & prop & state
목 차
1. React의 컨셉개념 정리.
2. JSX란
3. 컴포넌트란
4. prop & state
Ⅰ. React의 컨셉 개념 정리.
㉠. 리엑트의 특징.
㉡. CSR vs SSR
㉢. 리엑트가 하는 일.
◎ React Concept
※ React는 현재 현업에서 인기 있는 웹/앱(RN)의 View(UI)를 개발할 수 있도록 하는 JS-라이브러리입니다.
§ 보통 프로덕트(웹, 앱 혹은 테스크톱용 소프트웨어)을 만들기 위해서는
[ 유저가 조작하기 위한 UI(User-Interface) & UI를 컨트롤 하기 위한 로직 & 데이터를 처리하는 비즈니스 로직]
3가지 부분으로 개발이 필요합니다.
== 이렇게 특정 부분을 나누어 개발하는 방법론들을 " MVC패턴" * "MVVM패턴" 이라고 하며,
React는 이중에서 View 즉 유저가 조작하기 위한 UI를 만드는 것을 목표로 합니다.
㉠ React의 특징.
1. React는 "선언형(Declarative)" 입니다.
2. React는 "컴포넌트" 기반으로 '재사용성'이 뛰어납니다.
3. React는 "Virtual-DOM(가상돔)" 기반으로 가볍습니다.
4. React 컴포넌트는 state와 props를 가집니다.
1. React - 선언형(Declarative).
- React를 사용하면 자주 접할 수 있는 패러다임은
"선언형(Declartive)프로그래밍" 과 명령형(imperative) 프로그래밍입니다.
- 이중에서 선언형 성격을 정리해보자면,
리액트는 선언형 성격에 맞는 컴포넌트를 구현하기 위해 <tag><tag/> jsx문법을 통해 구현합니다.
== jsx를 얻기 위한 알고리즘에 대해서 따로 구현을 하지 않습니다.
ex)
document.createElement 혹은
해당 컴포넌트의 변경사항을 체크하는 알고리즘,
리-렌더링 여부 알고리즘에 대해서 따로 구현하지 않습니다.
☆ 선언형 특성은, 리액트를 사용할 때 "화면 설계" 라는 초점에 맞춰서 개발할 수 있도록 해주므로,
코드 구현에 있어서 고민을 최소화 해주어 높은 생산성을 보장할 수 있도록 해줍니다.
2. 컴포넌트 기반으로, 코드의 재사용성 증대 : Component Based Development
- "컴포넌트"라는 것ㄷ은 독립적인 단위의 SW모듈을 말합니다.
== 소프트웨어를 독립적인 하나의 부품으로 만드는 방법.
◇ React는 웹에서 쓰는 각 요소들을 컴포넌트로 만들 수 있도록 해서
기존의 UI를 구현한 코드를 다른 화면에서 가져다 다시 쓰거나,
다른 프로젝트에서 다시 쓸 수 있도록 하는 장점 ( "높은 재사용성")을 가집니다.
● 독립적인 코드 블럭( HTML + CSS + JavaScript )
● 중복되는*자주 사용되는 키워드(모달창, 버튼 등등..)를 하나의 컴포넌트로 표현하고 싶다
[ 이것을 기반으로 하는게 React ]
● 작업의 단위 = 컴포넌트.
HTML 요소와 컴포넌트를 비교해 보겠습니다.
먼저, <img src="이미지주소"/>와 같이 컴포넌트는 내가 지은 이름으로 태그를 만들 수 있습니다.
또한, img 태그에서 src를 설정해준 것처럼, 컴포넌트에서도 name을 Mark라고 설정할 수 있습니다.
img 태그는 이미지 주소를 바탕으로 이미지를 렌더링하지만,
컴포넌트는 해당 태그 안에서 어떤 로직이 작성되었는지는 모르겠지만, Mark라는 이름을 사용하여 표현 가능합니다.
HTML에서는 이를 어트리뷰트라고 하지만, 컴포넌트에서는 어트리뷰트 대신 prop이라고 부릅니다.
외부에서 <내가 지은 이름1> 태그 안으로 데이터를 전달하고 싶을 때 prop을 사용하며,
여러 개의 prop이 있을 경우 props라고 합니다.
이제 <button>버튼</button>에 주목해 보겠습니다. 버튼 태그 사이의 텍스트는 렌더링할 때 사용됩니다.
이는 컴포넌트에서도 마찬가지로 적용됩니다.
컴포넌트 태그 사이에 데이터를 담을 수 있으며, 이를 children이라고 합니다. children도 props 중 하나입니다.
결론적으로, <내가 지은 이름> 컴포넌트는 두 개의 prop을 받았습니다.
{ prop={false}, children="내용" }
이러한 객체의 이름은 props입니다, 이에 관련된 내용은 밑에서 정리하겠습니다.
컴포넌트를 활용하는 개발자들이 할 일은
props를 내려받음으로써 어떻게 표현하고 동작시킬지를 구현하는 것입니다.
3. Virtual DOM (가상돔) 기반.
Virtual DOM이라는 객체를 만들어두고, 가상의 DOM 트리 구조를 그려서
변경된 부분만을 체크하여, 실제 DOM에 반영하는 방식으로 브라우저를 렌더링합니다.
@ 주의할 점은, 변경된 사항이 없는 곳은 재랜더하지 않습니다,(렌더링 최적화 효과)
㉡ CSR vs SSR
◇ CSR [ Clinet Side Rendering ]
● 서버와의 통신을 통해 받아온 HTML/JS 데이터가 전부 다운로드 되어서,
화면을 한번에 그릴 수있기 전까지 화면이 유저에게 보이지 않습니다.
● 완전히 페이지의 데이터(HTML/JS)가 로드되어서, 화면이 나타난 후에야, 유저가 인터렉션 가능.
1. 서버가 빈 html을 response했습니다. (화면엔 아무것도 보이지 않는다.
- 이 중간에 '캐싱과정' 발생.
2. html안에 들어있는 JS 파일을 서버로 부터 다운로드합니다.
3. 브라우저가 다운로드된 JS 파일을 읽어서 실행합니다(JS 안에 react 라이브러리가 포함되어 있다).(아직 로딩상태)
4. 리액트 실행 직후에 현재 경로에 해당하는 페이지를 렌더링(이제 화면이 보이고 인터랙션 가능)
이 과정은 CSR을 활용해서 구현되어 있는 react 페이지를 사용자가 처음 방문할 때만 일어납니다.
◇ SSR [ Server Side Rendering ]
● HTML+JS가 전부 다운로드 되지 않더라도, 일단 화면상에는 보이지만 유저가 사용할 수 없습니다.
● HTML+JS가 전부 다운로드 되어, 리액트 앱이 정상 실행된 후, 유저가 사용 가능합니다.
1. 서버가 문자열로 이미 표현된 HTML을 내려줍니다.
2. 이 HTML을 클라이언트가 받는 순간 화면에 문서가 랜더링 됩니다.
화면에 출력되고 나서 파일안에 포함된 JS코드를 받아옵니다.
화면이 보이기는 하지만, 상호작용은 할 순 없는 단계입니다.
3. 리액트를 실행합니다. (이때까지도 동작하지 않습니다.)
4. 리액트가 실행된 후 인터렉션이 가능합니다.
☆ ☆ 사실상, 페이지를 렌더하는 것은 SSR 방식이지만,
react를 실행하는 것은 CSR 방식으로 합니다.
㉢ 리엑트가 하는 일.
☆ 리액트의 핵심 모듈 2개.
// 1. 리액트 컴포넌트 => HTMLElement 연결하기
import ReactDOM from 'react-dom';
// 2. 리액트 컴포넌트 만들기
import React from 'react';
리액트를 사용하기 위해서는 두 가지 모듈(라이브러리)이 필요합니다.
- React: 컴포넌트를 생성하는 데 사용됩니다. 예를 들어, <Hello name="Mark">와 같은 컴포넌트를 만들 수 있습니다.
- ReactDOM: 생성한 컴포넌트를 실제 페이지에 그리는 역할을 합니다.
ReactDOM에서 가장 많이 사용되는 함수는 render입니다. 이 함수는 무엇을, 어디에 그릴 것인지를 지정해 주며,
프로그램의 시작점인 main 역할을 합니다.
Ⅱ. JSX란?
◎ JSX란?
- JSX( Syntax Extension to JavaScript ) : 리엑트에서 생김새를 정의할 때 사용하는 문법.!
- JSX는 리엑트를 사용하여 개발할 때 거의 필수적으로 사용해야 합니다.
- 자바스크립트의 확장 문법이라는 의미.(공식적인 자바스크립트 문법은 아님)
-> 브라우저에서 실행하기 전에 'babel'을 사용하여 일반 JS형태의 코드로 변환됩니다.
- JSX는 하나의 파일에, JS와 HTML을 동시에 작성 가능하기 때문에 편리합니다.
- JSX는 내부적으로 XML, HTML 코드를 JS 코드로 변환하는 과정을 거치게 됩니다.
◇ JSX 코드를 JS 코드로 변환시켜주는 역할을 하는 것이 바로 "React의 'createElement ' 라는 함수입니다.
// JSX를 사용한 코드 //
class Hello extends React.Component{
render(){
return <div>Hello {this.props.toWhat}</div>;
}
}
ReactDOM.render(
<Hello toWhat="World"/>
document.getElementById('root')
);
Hello라는 이름을 가진 React 컴포넌트를 만들고,
컴포넌트 내부에서 JS코드와 HTML 코드가 결합된 JSX 코드를 사용하고 있습니다.
이런식으로 만들어진 컴포넌트를 ReactDOM의 렌더함수를 사용해, 실제 화면에 렌더링합니다.
// JSX를 사용하지 않은 코드 //
class Hello extends React.Component{
render(){
return React.createElement('div',null,`Hello ${this.props.toWhat}`);
}
}
ReactDOM.render(
React.createElement(Hello,{toWhat:'World'},null),
document.getElementById('root')
);
JS코드만을 사용해서 작성하는 경우에도 JSX로 작성한 코드와 비슷하긴합니다.
Hello 컴포넌트 내부에서 JSX를 사용했던 부분이 React.createElement라는 함수로 대체된 것을 확인 가능합니다
※여기서 확인 가능한 것은,
JSX문법을 사용하면 리엑트에서 내부적으로 모두 createElement 함수를 사용하도록 변환시켜준다는 것입니다.
이 creteElement 함수 호출의 결과로, 아래 코드와 같은 JS 객체가 나오게 됩니다.
// React.createElement()의 결과로 다음과 같은 결과의 객체가 생성된다.
const element ={
type:'h1',
props:{
className:'light',
children:'Hello, world!'
}
}
리엑트는 이 객체들을 읽어서 DOM을 만드는데 사용하고 항상 최신 상태로 유지합니다.
리액트에서는 이 객체를 element라고 부릅니다.
▼ createElement 함수의 파라미터 정리.
React.createElement(
type,
[props],
[...children]
)
- type : element의 유형, 타입을 나타냅니다.
==> div 혹은 span 같은 HTML 태그가 올 수도 있고, 다른 리액트 컴포넌트가 들어갈수도 있습니다.
- props: 속성이 들어갑니다.
- children: 현재 엘리먼트가 포함하고 있는 자식 엘리먼트,
★ JSX를 사용했을 때 코드가 더욱 간결해지고,
생산성과 가독성이 올라가기 때문에 사용하는 것을 권장합니다.
[ ■ JSX 사용 시 장점 ]
1. 코드가 간결해집니다.
: type, props, children 이라는 createElement의 파라미터들을 사용.
// JSX 사용함
<div>Hello, {name}</div>
// JSX 사용 안함
React.createElement('div',null,`Hello, ${name}`);
2. 가독성이 향상됩니다.
: 유지보수 관점에서 매우 중요.
- 가독성이 높을수록 코드상에 존재하는 버그 또한 쉽게 발견 가능.
3. Injection Attacks 방어.
* Injection Attacks : 입력창에 문자나 숫자 같은 일반적인 값이 아닌 소스코드를 입력하여,
해당 코드가 실행되도록 만드는 해킹 방법.
이 해킹 방법을 방어함으로써, 보완성이 올라갑니다.
const title = response.potentiallyMaliciousInput;
// 이 코드는 안전합니다.
const element = <h1>{title}</h1>
[ ■ JSX 사용 규칙. ]
- JSX는 JS 문법을 확장시킨 것이기 때문에, 모든 JS 문법을 지원합니다.
++ 추가로, XML과 HTML을 섞어서 사용합니다.
const name = 'developer';
const element = <h1>내 이름은 {name}</h1>;
ReactDOM.render(
element,
document.getElementById('root')
);
1 . 반드시 부모 요소 하나가 감싸는 형태여야 합니다.
: Virtual DOM에서 컴포넌트 변화를 감지할 때 효율적으로 비교할 수 있도록
컴포넌트 내부의 하나의 DOM 트리 구조로 이루어져야 한다는 규칙.
EX) 에러 케이스,
// Fail to compile
// parsing error : adjacent JSX elements be wrapped in an enclosing tag
// Did you want a JSX fragment <>...</>?
function App() {
return (
<div>Hello</div>
<div>GodDaeHee!</div>
);
}
EX) 정상 코드,(<div></div> 로 감싼 경우)
// div를 사용 하였기 때문에 스타일 적용시 작성한 코드를 div로 한번 더 감쌌다는 부분을 고려해야 한다.
function App() {
return (
<div>
<div>Hello</div>
<div>GodDaeHee!</div>
</div>
);
}
EX) 정상 코드,(<Fragment></Fragment> 로 감싼 경우)
// <Fragment>를 사용가능 하지만 <div>태그보다 무거운 편이다.
function App() {
return (
<Fragment>
<div>Hello</div>
<div>GodDaeHee!</div>
</Fragment>
);
}
EX) 정상 코드,(<></> 로 감싼 경우)
function App() {
return (
<>
<div>Hello</div>
<div>GodDaeHee!</div>
</>
);
}
2 . 자바스크립트 표현식.
: JSX 안에서도 JS 코드 표현식을 사용 가능합니다.
JS 표현식을 사용하려면 JSX 내부에서 코드를 {}로 감싸주면 됩니다.
+ 유효한 모든 JS 표식을 넣을 수 있습니다.
표현식과 연산자 - JavaScript | MDN
이번 장에서는 JavaScript의 표현식과 함께 할당, 비교, 산술, 비트 계산, 논리, 문자열, 삼항 등 다양한 연산자를 살펴보겠습니다.
developer.mozilla.org
function App() {
const name = 'GodDaeHee';
return (
<div>
<div>Hello</div>
<div>{name}!</div>
</div>
);
}
3 . if문(for 문) 대신 삼항 연산자(조건부 연산자) 사용.
- if문과 for 루프문은 JS 표현식이 아니기 때문에, JSX 내부 자바스크립트 표현식에서는 사용할 수 없습니다.
+ 조건부에 따라 렌더링 시 JSX 주변 코드에서 if문을 넣어주거나,
{} 안에서 삼항 연산자(조건부 연산자)를 사용해야합니다.
EX) 방법 1 : JSX 외부에서 사용.
function App() {
let desc = '';
const loginYn = 'Y';
if(loginYn === 'Y') {
desc = <div>GodDaeHee 입니다.</div>;
} else {
desc = <div>비회원 입니다.</div>;
}
return (
<>
{desc}
</>
);
}
EX) 방법 2 : JSX 내부에서 사용. (삼항연산자)
function App() {
const loginYn = 'Y';
return (
<>
<div>
{loginYn === 'Y' ? (
<div>GodDaeHee 입니다.</div>
) : (
<div>비회원 입니다.</div>
)}
</div>
</>
);
}
EX) 방법 3 : AND 연산자(&&) 사용.
// 조건이 만족하지 않을 경우 아무것도 노출되지 않는다.
function App() {
const loginYn = 'Y';
return (
<>
<div>
{loginYn === 'Y' && <div>GodDaeHee 입니다.</div>}
</div>
</>
);
}
EX) 방법 4 : 즉시 실행함수 사용.
function App() {
const loginYn = 'Y';
return (
<>
{
(() => {
if(loginYn === "Y"){
return (<div>GodDaeHee 입니다.</div>);
}else{
return (<div>비회원 입니다.</div>);
}
})()
}
</>
);
}
4 . ReactDom은 HTML 어트리뷰트 이름 대신, camelCase 프로퍼티 명명 규칙을 사용합니다.
4-1. JSX 스타일링.
- JSX에서 JS 문법을 사용하려면 {}를 써야 하기 때문에,
스타일 적용시에도 객체 형태로 넣어주어야합니다.
- 카멜 표기법으로 작성해야 합니다.( ex: font-size ==> fontSize )
ex) css style
function App() {
const style = {
backgroundColor: 'green',
fontSize: '12px'
}
return (
<div style={style}>Hello, GodDaeHee!</div>
);
}
4-2. class 대신 className
- 일반 HTML에서 CSS 클래스를 사용할 때에는 calss라는 속성을 사용
--> JSX에서는 class가 아닌, className을 사용합니다.
ex) className
function App() {
const style = {
backgroundColor: 'green',
fontSize: '12px'
}
return (
<div className="testClass">Hello, GodDaeHee!</div>
);
}
5 . JSX내에서 주석 사용 방법.
- JSX 내에서 {/*...*/} 와 같은 형식을 사용합니다.
function App() {
return (
<>
{/* 주석사용방법 */}
<div>Hello, GodDaeHee!</div>
</>
);
}
Ⅲ. 컴포넌트란?
§ 컴포넌트는 리액트의 꽃이라 불릴 정도로 리액트에서 가장 중요한 요소입니다.
★ 컴포넌트(Component)란?
√ 리액트로 만들어진 앱을 구성하는 최소한의 단위.
√ 기존 웹 프레임워크는 MVC 방식으로 분리*관리하면서 각 요소의 의존성이 높아서
코드의 재활용이 어렵다는 단점이 있었습니다.
반면에, 컴포넌트를 활용하면 MVC의 뷰(View)를 독립적으로 구성하여 재사용 가능하고
새로운 컴포넌트로도 쉽게 만들 수 있습니다.
√ '컴포넌트'는 데이터(props)를 입력받아서 View(state) 상태에 따라 'DOME Node'를 출력하는 함수 !
√ "props" 라는 임의의 입력을 받은 후, 화면에 어떻게 표시되는지를 기술하는 React 엘리먼트를 반환합니다.
√ '컴포넌트'의 이름은 항상 ! 대문자로 시작하도록 합니다.
(리액트는 소문자로 시작하는 컴포넌트를 DOM 태그로 취급하기 때문.)
√ UI를 재사용 가능한, 개별적인 여러 조각으로 나누고, 각 조각을 개별적으로 나누어 코딩합니다.
√ props와 state 등의 특징들은 밑에서 정리.
ex) 컴포넌트 활용 예시.
: 글 목록 컴포넌트 1개, 결과 컴포넌트 1개를 생성하고 활용해 화면을 구성 가능합니다.
이걸 다른 방식으로 재사용하면?
★ 컴포넌트(Component) 의 종류.
- 리엑트에서 정의하는 컴포넌트 종류는 크게 함수형 컴포넌트 & 클래스형 컴포넌트 2가지가 있습니다.
1) 함수형 컴포넌트 ( Stateless Functional Component )
- 가장 간단하게 컴포넌트를 정의하는 방법은 '자바스크립트 함수'를 작성하는 것 입니다.
ex) MyComponent 라는 파일을 다른 파일에서 import해서 사용 가능하도록 정의하려면
import React from 'react';
function MyComponent(props) {
return <div>Hello, {props.name}</div>;
}
export default MyComponent; //다른 JS파일에서 불러올 수 있도록 내보내주기
*import 시에 js, 혹은 jsx 등의 파일 확장자를 생략해도,찾아지는 것은 "웹팩-코드 검색-확장자" 기능 때문.
ex)
- Header.js / Footet.js / Main.js 생성
- rsf(React Stateless Functional Component) 를 설치하고 입력.
import React from 'react';
function Header(props) {
return (
<div>
<header>
<h1>헤더입니다.</h1>
</header>
</div>
);
}
export default Header; //다른 JS파일에서 불러올 수 있도록 내보내주기
import React from 'react';
function Footer(props) {
return (
<div>
<footer>
<h1>푸터입니다.</h1>
</footer>
</div>
);
}
export default Footer; //다른 JS파일에서 불러올 수 있도록 내보내주기
import React from 'react';
function Main(props) {
return (
<div>
<main>
<h1>안녕하세요. 갓대희 입니다.</h1>
</main>
</div>
);
}
export default Main; //다른 JS파일에서 불러올 수 있도록 내보내주기
- 만들어진 컴포넌트들을 App.js에서 조합해주면.
import React, { Component } from 'react'; // 리액트를 구현할 수 있는 플러그인을 연결
import Header from './component/Header';
import Footer from './component/Footer';
import Main from './component/Main';
// JS파일에 외부 파일을 불러오는 것이기 때문에 "import" 키워드를 사용한다.
// 같은 JS파일은 확장자를 사용하지 않는다.
function App() {
return (
<div>
<Header />
<Main />
<Footer />
</div>
);
}
export default App; //다른 JS파일에서 불러올 수 있도록 내보내주기
2) 클래스형 컴포넌트 ( Class Component )
- 컴포넌트 구성 요소, 리액트 생명주기를 모두 포함하고 있습니다.
- 프로퍼티, state, 생명주기 함수가 필요한 구조의 컴포넌트를 만들 때 사용합니다.
import React from 'react';
class MyComponent extends React.Component {
constructor(props) { // 생성함수
super(props);
}
componentDidMount() { // 상속받은 생명주기 함수
}
render() { // 상속받은 화면 출력 함수, 클래스형 컴포넌트는 render() 필수
return <div>Hello, {this.props.name}</div>;
}
}
export default MyComponent; //다른 JS파일에서 불러올 수 있도록 내보내주기
ex)
- Header.js / Footet.js / Main.js 생성
- rcc(React Class Component) 를 설치하고 입력.
import React, { Component } from 'react';
class Header extends Component {
render() { //HTML을 웹 페이지에 렌더링 한다.
return (
<div>
<header>
<h1>헤더입니다.</h1>
</header>
</div>
);
}
}
export default Header; //다른 JS파일에서 불러올 수 있도록 내보내주기
import React, { Component } from 'react';
class Footer extends Component {
render() {
return (
<div>
<footer>
<h1>푸터입니다.</h1>
</footer>
</div>
);
}
}
export default Footer; //다른 JS파일에서 불러올 수 있도록 내보내주기
import React, { Component } from 'react';
class Main extends Component {
render() {
return (
<div>
<main>
<h1>안녕하세요. 갓대희 입니다.</h1>
</main>
</div>
);
}
}
export default Main; //다른 JS파일에서 불러올 수 있도록 내보내주기
- 만들어진 컴포넌트들을 App.js에서 조합해주면.
import React, { Component } from 'react'; // 리액트를 구현할 수 있는 플러그인을 연결
import Header from './component/Header';
import Footer from './component/Footer';
import Main from './component/Main';
// JS파일에 외부 파일을 불러오는 것이기 때문에 "import" 키워드를 사용한다.
// 같은 JS파일은 확장자를 사용하지 않는다.
function App() {
return (
<div>
<Header />
<Main />
<Footer />
</div>
);
}
export default App; //다른 JS파일에서 불러올 수 있도록 내보내주기
Ⅳ. props & state ?
▼ Props.
● 컴포넌트는, 데이터를 가진 하나의 'props' 객체 인자를 받은 후 React 엘리먼트를 반환합니다.
--> 이때 props는 속성을 나타내는 데이터입니다.
● props는 컴포넌트에서 컴포넌트로 전달하는 데이터 입니다.
--> 컴포넌트의 속성으로, 해당 컴포넌트를 불러와 사용하는 부모 컴포넌트에서만 설정 가능합니다.
▽ Props 지정하기.
● props는 <ComponentName prop1={propValue1} prop2={propValue2} ... /> 의 형태로
컴포넌트를 부를 때 함께 지정합니다.
ex) Dog 컴포넌트에 name prop와 age prop를 지정.
<Dog name="Ari" age={10} />
<Dog name="Bori" age={7} />
● 같은 타입의 컴포넌트에 다른 props값을 주어서, 패턴이 반복되는 형태로 컴포넌트의 효율적인 재사용이 가능.
● props에는 불리언 값(true, false), 숫자, 배열과 같은 다양한 형태의 데이터를 담을 수 있습니다.
- 공백 구분으로 여러 개를 담는 것도 가능합니다.
- props에 있는 데이터는 문자열인 경우를 제외하면, 모두 중괄호({})로 값을 감싸야 합니다.
▽ Props 받아서 사용하기.
● props는 '읽기 전용'이므로, 컴포넌트의 내부에서 props를 수정해서는 안됩니다.
● props를 받는 함수형 컴포넌트에 인자를 정의하면, props를 속성으로 가지는 객체가 해당 인자로 전달됩니다.
-> 컴포넌트 내부에서 사용할 시에는 객체에 존재하는 값을 가져오듯 점 연산자(.)를 사용하여
원하는 props를 꺼내 쓸 수 있고, 이를 중괄호로 감싸서 { [인자 이름].[props 이름] } 형태로 사용
// 객체 인자를 통해 props 받아오기
function Dog(props) {
return {
<div>{props.name}</div>
<div>{props.age}</div>
}
}
● props를 받을 때, 구조분해할당을 사용하여 점 연산자 사용을 줄일 수 있습니다.
// 객체 인자를 구조 분해 할당하여 props 받아오기
function Dog({ name, age }) {
return {
<div>{name}</div>
<div>{age}</div>
}
}
● props-types' 라이브러리를 통해 컴포넌트의 특별한 프로퍼티인 propTypes를 선언하여,
컴포넌트가 받은 props의 타입을 확인하거나,
defaultProps 프로퍼티를 할당하여 props의 초기값을 정의할 수 있습니다.
// 컴포넌트 props 초기값 지정
Dog.defaultProps = {,
name: '이름',
age: 0,
}
// 컴포넌트 props 타입 확인
Dog.propsTypes = {,
name: PropTypes.string.isRequired,
age: PropTypes.number,
}
● "클래스형 컴포넌트" 에서 props를 사용할 때는 this.props로 불러와서 사용합니다.
-> 클래스형 컴포넌트에서 propsTypes 혹은 defaultProps를 사용할 때는, 클래스 내부에서도 지정 가능. !
// 클래스형 컴포넌트에서 props 사용하기
class Dog extends React.Component {
static defaultProps = { ... }; // 컴포넌트 props 초기값 지정
static propTypes = { ... }; // 컴포넌트 props 타입 확인
render() {
// 구조 분해 할당으로 props 사용
const { name, age } = this.props;
return <div>{name}</div>;
}
}
▼ state
● state는 "컴포넌트 내부의 동적 데이터" 를 의미합니다.
- props는 부모 컴포넌트가 설정하는 값으로 컴포넌트 자신은 props를 읽기 전용으로만 사용 가능합니다.
● state를 사용하는 방식에는, 컴포넌트 종류에 따라 2가지가 있습니다.
- 클래스형 컴포넌트에서는 컴포넌트 자체가 state를 지니는 방식으로 사용합니다.
- 함수형 컴포넌트에서는 useState라는 함수, Hook을 통해 사용합니다.
● 여러 개의 자식으로부터 데이터를 모으거나, 두 개의 자식 컴포넌트들이 서로 통신하게 하기 위해서
부모 컴포넌트에 state를 정의합니다.
=== 부모 컴포넌트가 props를 사용하여 자식 컴포넌트에 state를 다시 전달함으로 서로 동기화합니다.
-> 두 컴포넌트 간 state값을 동기화하는 일, state를 공유하는 일 등등은
그 state 값을 필요로 하는 컴포넌트 간의 가장 가까운 부모 컴포넌트로 state를 끌어올려서 가능합니다.
★ ★
==>> 여러 개의 컴포넌트 간의 state를 동기화시키기보다,
공통 부모로 끌어올려서 하향식 데이터 흐름을 이용하는게 좋습니다.
▽ Class Component에서 state 사용하기.
● 클래스형 컴포넌트에서 state를 사용할 때는 객체 형식의 this.state를 통해
state 객체의 초기값을 설정하고 조회 가능합니다.
● state 값을 변경할 경우, this.setState를 사용하여 새로운 값을 넣을수도 있습니다.
class ClassExample extends React.Component {
constructor(props) {
super(props);
// state 초기값 설정
this.state = {
count: 0,
};
}
render() {
const { count } = this.state; // state 조회
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => {
this.setState({ // this.setState를 통해 state 업데이트
count: count + 1
});
}}>
Click me
</button>
</div>
);
}
}
}
▽ Function Component에서 state 사용하기.
● Hool이 16.8 이후로 새로 추가되면서, Function Component에서도
상태값과 여러 React의 기능을 사용할 수 있게 됨.
'Front_End [JS기반] > React.js + Next.js' 카테고리의 다른 글
[ 3D Web : Front & Back_Next.JS ] Next.JS의 렌더링이 동작하는 원리. (2) | 2024.11.28 |
---|---|
[ 3D Web : Front_React.js ] React.JS : React란? (0) | 2024.11.26 |
[ 3D Web : Front & Back_Next.JS ] Next.JS란 무엇이고, 왜 사용하는걸까 (4) | 2024.11.25 |
[ 3D Web : Front_React.js ] React의 동작원리 정리. (1) | 2024.11.21 |
[ 3D Web : Front_React.js ] React란 무엇인가? (1) | 2024.11.20 |