리액트 문법
https://velog.io/@edie_ko/React-JSX%EB%9E%80-%EB%A0%8C%EB%8D%94%EB%A7%81-Rendering%EC%9D%B4%EB%9E%80
React | JSX란? 렌더링 Rendering이란?
JSX를 정리하기에 앞서 간단히 리액트를 정리해보자. 리액트는 페이스북이 만든 사용자 UI 구축을 위한 라이브러리이다. 하나의 단일 url을 가지고 SPA(Single Page Application)으로 사이트를 표현하는
velog.io
[React] 리액트를 처음부터 배워보자. —01. React.js란 무엇인가?
이 글을 남기는 계기는 Dan Ambramov의 블로그 Overreacted를 보며 React.js에 대해 더 깊이 공부할 필요성을 느꼈기 때문이다.
medium.com
[React] 리액트를 처음부터 배워보자. — 02. React.createElement와 React.Component 그리고 ReactDOM.render의
이 글을 남기는 계기는 Dan Ambramov의 블로그 Overreacted를 보며 React.js에 대해 더 깊이 공부할 필요성을 느꼈기 때문이다.
medium.com
https://velog.io/@soyi47/React-Component-props-state
[React] Component와 props, state
🚀 Component, props, state에 대해 알아본다.
velog.io
[React.JS] React 기초 학습내용 정리
본 포스팅은 inflearn의 'React & Express 를 이용한 웹 어플리케이션 개발하기' 강좌 내용을 포함하고 있습니다.링크: https://www.inflearn.com/course/react-%EA%B0%95%EC%A2%8C-velopert프레임워
velog.io
React.js => MVC 패턴, MVVM패턴 중 View
=> 사용자가 조작하기 위한 UI를 만드는 것을 도와주는 라이브러리
1. JSX 문법 : 자바스크립트 안에서 html 문법 사용
( => React.createElement()를 호출하기 위한 방법일 뿐, Babel(js 트랜스파일러)을 통해 파싱되고 트랜스 파일링됨 )
- 속성은 쌍따옴표로 감싸기 ex. className="a"
- 태그는 항상 닫아야 함
- 모든 태그는 self-closing 가능 ex. <input />
- 가장 외곽에 wrap할 태그 필요 (형제 노드 작성 불가)
- render 안에서 js 변수 정의, return 에서 중괄호 감싸며 표현
- Element Rendering : html요소(element) 또는 React요소 등의 코드가 눈으로 볼 수 있도록 그려지는 것
엘리먼트는 React의 가장 작은 단위
엘러먼트는 화면에 표시할 내용을 담음.
브라우저 DOM 엘리먼트와는 다르게 React 엘리먼트는 일반 객체이며 쉽게 생성 가능
React DOM은 React 엘리먼트와 일치하도록 DOM을 업데이트함
ReactDOM.render 함수 => React 요소가 DOM node에 추가되어 화면에 렌더됨
첫 번째 인자: JSX로 넘길 React 요소 인자
두 번째 인자: 첫번째 인자를 렌더할 container(부모요소) 인자
2. Component 및 재사용성
컴포넌트 : 독립적인 단위의 소프트웨어 모듈
웹에서 쓰는 각 요소들을 컴포넌트로 생성 -> 기존의 UI를 다른 화면, 다른 프로젝트에서 재사용 가능
함수형 : return문에서 JSX를 반환
클래스형 : React.Component 클래스를 상속 / 컴포넌트는 jsx를 반환해야 하는데, 클래스는 return문 사용 불가 -> render()함수를 이용해 return 작성
3. Virtual DOM
메모리 단에서 컴포넌트 정보를 생성하고 비교 -> 전체 DOM 트리가 업데이트가 필요한 경우 이를 반영하는 방식
바뀌지 않은 부분과 바뀐 부분을 자동으로 감지해서 업데이트
4. states, props
props : 부모 컴포넌트가 자식 컴포넌트에게 주는 값 / 자식 컴포넌트에서는 받아온 props 를 직접 수정 불가, event 이용해 수정 가능
ex. <Dog name="Ari" age={10} />
state : 컴포넌트 내부에서 선언, 내부에서 값 변경 가능
클래스형 컴포넌트 - 컴포넌트 자체가 state를 지니는 방식으로 사용
함수형 컴포넌트 - useState, Hook을 통해 사용
5. 선언형
컴포넌트(원하는 결과, 뷰)를 얻기 위해 jsx 문법을 이용
즉, jsx를 얻기 위한 구체적 알고리즘에 대한 구현 X
ex. document.createElement / 컴포넌트의 변경사항을 체크하는 알고리즘 / 리-렌더링 여부에 대한 알고리즘 구현 X
- App.js (수정 전)
import { Component } from 'react';
import './App.css';
import Subject from './Subject';
import TOC from './TOC'
import Content from './Content'
class App extends Component{
render(){
return (
<div className='App'>
<Subject title='웹 카페' sub='웹에 대해 알아봅시다!'></Subject>
<Subject title='리액트' sub='리액트에 대해 알아봅시다'></Subject>
<TOC></TOC>
<Content title='HTML5에 대해' desc='홈페이지의 뼈대를 말한다'></Content>
</div>
);
}
}
export default App;
- 수정 후
import { Component } from 'react';
import './App.css';
import Subject from './components/Subject';
import TOC from './components/TOC'
import Content from './components/Content'
class App extends Component{
constructor(props){ //컴포넌트가 render 되기 전 props 값으로 보낼 속성값(subject) 초기화
super(props);
this.state={ //state: 상태값 저장
subject:{title:'웹카페',sub:'웹에 대해 알아봅시다'} //subject state 생성
}
}
render(){ //JSW 반환 위해 작성 (return문 작성)
return ( //제작한 JSX 컴포넌트 넣기
<div className='App'>
<Subject title={this.state.subject.title} /* this=App / 중괄호 필수 */
sub={this.state.subject.sub}></Subject>
<TOC></TOC>
<Content title='HTML5에 대해' desc='홈페이지의 뼈대를 말한다'></Content>
</div>
);
}
}
export default App;
- 컴포넌트에 state 전달 (props로?)
- App.js
import { Component } from 'react';
import './App.css';
import Subject from './components/Subject';
import TOC from './components/TOC'
import Content from './components/Content'
class App extends Component{
constructor(props){ //속성 초기화
super(props);
this.state={ //state: 상태값
subject:{title:'웹카페',sub:'웹에 대해 알아봅시다'},
contents:[ //배열 객체
{id:1, title:'HTML5에 대해', desc:'홈페이지의 뼈대를 말한다'},
{id:2, title:'CSS3의 모든 것', desc:'홈페이지를 꾸미고 레이아웃을 설정한다'},
{id:3, title:'Javascript란', desc:'정적인 홈페이지를 동적으로 만든다'}
]
}
}
render(){
return ( //제작한 컴포넌트 넣기
<div className='App'>
<Subject title={this.state.subject.title} sub={this.state.subject.sub}></Subject>
<TOC data={this.state.contents}></TOC>
<Content title='HTML5에 대해' desc='홈페이지의 뼈대를 말한다'></Content>
</div>
);
}
}
export default App;
- TOC.js
import { Component } from 'react';
class TOC extends Component{
render(){
let lists=[];
let data=this.props.data;
let i=0;
while(i<data.length){
lists.push(<li key={data[i].id}><a href={"/content/"+data[i].id}>{data[i].title}</a></li>);
i++;
}
return(
<nav>
<ul>
{lists}
</ul>
</nav>
);
}
}
export default TOC;
- App.js
import { Component } from 'react';
import './App.css';
import Subject from './components/Subject';
import TOC from './components/TOC'
import Content from './components/Content'
class App extends Component{
constructor(props){ //컴포넌트의 속성 초기화
super(props);
this.state={ //state: 상태값
mode:'welcome', //read로 변경하면 html5 설명 나옴
subject:{title:'웹카페',sub:'웹에 대해 알아봅시다'},
welcome:{title:'환영합니다',desc:'웹카페 홈페이지 방문을 환영합니다'},
contents:[ //배열 객체
{id:1, title:'HTML5에 대해', desc:'홈페이지의 뼈대를 말한다'},
{id:2, title:'CSS3의 모든 것', desc:'홈페이지를 꾸미고 레이아웃을 설정한다'},
{id:3, title:'Javascript란', desc:'정적인 홈페이지를 동적으로 만든다'}
]
}
}
render(){ //state 값 바뀌면 render 함수 재호출
console.log('App 컴포넌트 렌더링됨');
let _title, _desc = null; //컴포넌트 담을 변수 앞에 _ 입력할 것
if (this.state.mode==='welcome'){
_title=this.state.welcome.title;
_desc=this.state.welcome.desc;
} else if (this.state.mode==='read') {
_title=this.state.contents[0].title;
_desc=this.state.contents[0].desc;
}
return ( //제작한 컴포넌트 넣기
<div className='App'>
<Subject title={this.state.subject.title} sub={this.state.subject.sub}></Subject>
<TOC data={this.state.contents}></TOC>
<Content title={_title} desc={_desc}></Content>
</div>
);
}
}
export default App;
- Subject.js
import { Component } from 'react';
class Subject extends Component{
render(){
console.log('Subject 컴포넌트가 렌더링됨');
return(
<header>
<h1><a href='/'>{this.props.title}</a></h1>
<p>{this.props.sub}</p>
</header>
);
}
}
export default Subject;
- Content.js
import { Component } from 'react';
class Content extends Component{
render(){
console.log('Content 컴포넌트가 렌더링됨');
return(
<article>
<h2>{this.props.title}</h2>
<p>{this.props.desc}</p>
</article>
);
}
}
export default Content;
- TOC.js
import { Component } from 'react';
class TOC extends Component{
render(){
console.log('TOC 컴포넌트가 렌더링됨');
let lists=[];
let data=this.props.data;
let i=0;
while(i<data.length){
lists.push(<li key={data[i].id}><a href={"/content/"+data[i].id}>{data[i].title}</a></li>);
i++;
}
return(
<nav>
<ul>
{lists}
</ul>
</nav>
);
}
}
export default TOC;
- event 처리
- App.js
import { Component } from 'react';
import './App.css';
import Subject from './components/Subject';
import TOC from './components/TOC'
import Content from './components/Content'
class App extends Component{
constructor(props){ //컴포넌트의 속성 초기화
super(props);
this.state={ //state: 상태값
mode:'welcome',
subject:{title:'웹카페',sub:'웹에 대해 알아봅시다'},
welcome:{title:'환영합니다',desc:'웹카페 홈페이지 방문을 환영합니다'},
contents:[ //배열 객체
{id:1, title:'HTML5에 대해', desc:'홈페이지의 뼈대를 말한다'},
{id:2, title:'CSS3의 모든 것', desc:'홈페이지를 꾸미고 레이아웃을 설정한다'},
{id:3, title:'Javascript란', desc:'정적인 홈페이지를 동적으로 만든다'}
]
}
}
//state 값 바뀌면 render 함수 재호출
render(){
console.log('App 컴포넌트가 렌더링됨');
let _title, _desc=null;
if (this.state.mode==='welcome'){ //this=App
_title=this.state.welcome.title;
_desc=this.state.welcome.desc;
} else if (this.state.mode==='read') {
_title=this.state.contents[0].title;
_desc=this.state.contents[0].desc;
}
return ( //제작한 컴포넌트 넣기
<div className='App'>
{/* Subject 컴포넌트 잠시 사용 안 함
<Subject title={this.state.subject.title} sub={this.state.subject.sub}></Subject>
*/}
<header>
<h1>
<a href='/' onClick={function(event){
console.log(event);
debugger; //브라우저가 해당 시점 코드에서 멈춤, 소스로 자동 이동
alert('안녕하세요');
}}>
{this.state.subject.title}
</a>
</h1>
<p>{this.state.subject.sub}</p>
</header>
<TOC data={this.state.contents}></TOC>
<Content title={_title} desc={_desc}></Content>
</div>
);
}
}
export default App;
=>h1 클릭시 새로 고침됨 / but 리액트는 내용만 바뀌는 걸 지향 (SPA)
=> a 클릭시 새로고침되는 기본이벤트 제거
=>
import { Component } from 'react';
import './App.css';
import Subject from './components/Subject';
import TOC from './components/TOC'
import Content from './components/Content'
class App extends Component{
constructor(props){ //컴포넌트의 속성 초기화
super(props);
this.state={ //state: 상태값
mode:'read',
subject:{title:'웹카페',sub:'웹에 대해 알아봅시다'},
welcome:{title:'환영합니다',desc:'웹카페 홈페이지 방문을 환영합니다'},
contents:[ //배열 객체
{id:1, title:'HTML5에 대해', desc:'홈페이지의 뼈대를 말한다'},
{id:2, title:'CSS3의 모든 것', desc:'홈페이지를 꾸미고 레이아웃을 설정한다'},
{id:3, title:'Javascript란', desc:'정적인 홈페이지를 동적으로 만든다'}
]
}
}
//state 값 바뀌면 render 함수 재호출
render(){ //render: export 도움
console.log('App 컴포넌트가 렌더링됨');
let _title, _desc=null; //컴포넌트 담을 변수 앞에 _ 입력할 것
if (this.state.mode==='welcome'){ //this=App
_title=this.state.welcome.title;
_desc=this.state.welcome.desc;
} else if (this.state.mode==='read') {
_title=this.state.contents[0].title;
_desc=this.state.contents[0].desc;
}
return ( //제작한 컴포넌트 넣기
<div className='App'>
{/* Subject 컴포넌트 잠시 사용 안 함
<Subject title={this.state.subject.title} sub={this.state.subject.sub}></Subject>
*/}
<header>
<h1>
<a href='/' onClick={function(event){
console.log(event);
event.preventDefault();
}}>
{this.state.subject.title}
</a>
</h1>
<p>{this.state.subject.sub}</p>
</header>
<TOC data={this.state.contents}></TOC>
<Content title={_title} desc={_desc}></Content>
</div>
);
}
}
export default App;
=>h1 클릭 시 내용 바꾸기
=>
import { Component } from 'react';
import './App.css';
import Subject from './components/Subject';
import TOC from './components/TOC'
import Content from './components/Content'
class App extends Component{
constructor(props){ //컴포넌트의 속성 초기화
super(props);
this.state={ //state: 상태값
mode:'read',
subject:{title:'웹카페',sub:'웹에 대해 알아봅시다'},
welcome:{title:'환영합니다',desc:'웹카페 홈페이지 방문을 환영합니다'},
contents:[ //배열 객체
{id:1, title:'HTML5에 대해', desc:'홈페이지의 뼈대를 말한다'},
{id:2, title:'CSS3의 모든 것', desc:'홈페이지를 꾸미고 레이아웃을 설정한다'},
{id:3, title:'Javascript란', desc:'정적인 홈페이지를 동적으로 만든다'}
]
}
}
//state 값 바뀌면 render 함수 재호출
render(){ //render: export 도움
console.log('App 컴포넌트가 렌더링됨');
let _title, _desc=null; //컴포넌트 담을 변수 앞에 _ 입력할 것
if (this.state.mode==='welcome'){ //this=App
_title=this.state.welcome.title;
_desc=this.state.welcome.desc;
} else if (this.state.mode==='read') {
_title=this.state.contents[0].title;
_desc=this.state.contents[0].desc;
}
return ( //제작한 컴포넌트 넣기
<div className='App'>
{/* Subject 컴포넌트 잠시 사용 안 함
<Subject title={this.state.subject.title} sub={this.state.subject.sub}></Subject>
*/}
<header>
<h1>
<a href='/' onClick={function(event){
console.log(event);
event.preventDefault();
this.state.mode='welcome'; //state undefined 에러 발생
}}>
{this.state.subject.title}
</a>
</h1>
<p>{this.state.subject.sub}</p>
</header>
<TOC data={this.state.contents}></TOC>
<Content title={_title} desc={_desc}></Content>
</div>
);
}
}
export default App;
=> 에러 발생
=>
- bind로 함수-this 연결
import { Component } from 'react';
import './App.css';
import Subject from './components/Subject';
import TOC from './components/TOC'
import Content from './components/Content'
class App extends Component{
constructor(props){ //컴포넌트의 속성 초기화
super(props);
this.state={ //state: 상태값
mode:'read',
subject:{title:'웹카페',sub:'웹에 대해 알아봅시다'},
welcome:{title:'환영합니다',desc:'웹카페 홈페이지 방문을 환영합니다'},
contents:[ //배열 객체
{id:1, title:'HTML5에 대해', desc:'홈페이지의 뼈대를 말한다'},
{id:2, title:'CSS3의 모든 것', desc:'홈페이지를 꾸미고 레이아웃을 설정한다'},
{id:3, title:'Javascript란', desc:'정적인 홈페이지를 동적으로 만든다'}
]
}
}
//state 값 바뀌면 render 함수 재호출
render(){ //render: export 도움
console.log('App 컴포넌트가 렌더링됨');
let _title, _desc=null; //컴포넌트 담을 변수 앞에 _ 입력할 것
if (this.state.mode==='welcome'){ //this=App
_title=this.state.welcome.title;
_desc=this.state.welcome.desc;
} else if (this.state.mode==='read') {
_title=this.state.contents[0].title;
_desc=this.state.contents[0].desc;
}
return ( //제작한 컴포넌트 넣기
<div className='App'>
{/* Subject 컴포넌트 잠시 사용 안 함
<Subject title={this.state.subject.title} sub={this.state.subject.sub}></Subject>
*/}
<header>
<h1>
<a href='/' onClick={function(event){
console.log(event);
event.preventDefault();
this.state.mode='welcome'; //state undefined 에러 발생 => this의 주체가 없음
}.bind(this)}> //function을 this와 연관시킴
{this.state.subject.title}
</a>
</h1>
<p>{this.state.subject.sub}</p>
</header>
<TOC data={this.state.contents}></TOC>
<Content title={_title} desc={_desc}></Content>
</div>
);
}
}
export default App;
=> this 연결해도 클릭 시 변화 X
=> 값을 mode에 넣었지만 리액트가 인지 못해서 다시 render 안 함
=>
import { Component } from 'react';
import './App.css';
import Subject from './components/Subject';
import TOC from './components/TOC'
import Content from './components/Content'
class App extends Component{
constructor(props){ //컴포넌트의 속성 초기화
super(props);
this.state={ //state: 상태값
mode:'read',
subject:{title:'웹카페',sub:'웹에 대해 알아봅시다'},
welcome:{title:'환영합니다',desc:'웹카페 홈페이지 방문을 환영합니다'},//
contents:[ //배열 객체
{id:1, title:'HTML5에 대해', desc:'홈페이지의 뼈대를 말한다'},
{id:2, title:'CSS3의 모든 것', desc:'홈페이지를 꾸미고 레이아웃을 설정한다'},
{id:3, title:'Javascript란', desc:'정적인 홈페이지를 동적으로 만든다'}
]
}
}
//state 값 바뀌면 render 함수 재호출
render(){ //render: export 도움
console.log('App 컴포넌트가 렌더링됨');
let _title, _desc=null; //컴포넌트 담을 변수 앞에 _ 입력할 것
if (this.state.mode==='welcome'){ //this=App
_title=this.state.welcome.title;
_desc=this.state.welcome.desc;
} else if (this.state.mode==='read') {
_title=this.state.contents[0].title;
_desc=this.state.contents[0].desc;
}
return ( //제작한 컴포넌트 넣기
<div className='App'>
{/* Subject 컴포넌트 잠시 사용 안 함
<Subject title={this.state.subject.title} sub={this.state.subject.sub}></Subject>
*/}
<header>
<h1>
<a href='/' onClick={function(event){
console.log(event);
event.preventDefault();
this.setState({ //생성자에서 이미 setting된 값을 동적으로 바꿀 때 사용
mode:'welcome'
});
}.bind(this)}>
{this.state.subject.title}
</a>
</h1>
<p>{this.state.subject.sub}</p>
</header>
<TOC data={this.state.contents}></TOC>
<Content title={_title} desc={_desc}></Content>
</div>
);
}
}
export default App;
- App.js
import { Component } from 'react';
import './App.css';
import Subject from './components/Subject';
import TOC from './components/TOC'
import Content from './components/Content'
class App extends Component{
constructor(props){ //컴포넌트의 속성 초기화
super(props);
this.state={ //state: 상태값
mode:'read',
subject:{title:'웹카페',sub:'웹에 대해 알아봅시다'},
welcome:{title:'환영합니다',desc:'웹카페 홈페이지 방문을 환영합니다'},
contents:[ //배열 객체
{id:1, title:'HTML5에 대해', desc:'홈페이지의 뼈대를 말한다'},
{id:2, title:'CSS3의 모든 것', desc:'홈페이지를 꾸미고 레이아웃을 설정한다'},
{id:3, title:'Javascript란', desc:'정적인 홈페이지를 동적으로 만든다'}
]
}
}
//state 값 바뀌면 render 함수 재호출
render(){ //render: export 도움
console.log('App 컴포넌트가 렌더링됨');
let _title, _desc=null; //컴포넌트 담을 변수 앞에 _ 입력할 것
if (this.state.mode==='welcome'){ //this=App
_title=this.state.welcome.title;
_desc=this.state.welcome.desc;
} else if (this.state.mode==='read') {
_title=this.state.contents[0].title;
_desc=this.state.contents[0].desc;
}
console.log('render',this); //렌더의 주체 :App 컴포넌트
return ( //제작한 컴포넌트 넣기
<div className='App'>
{/* Subject 컴포넌트 잠시 사용 안 함
<Subject title={this.state.subject.title} sub={this.state.subject.sub}></Subject>
*/}
<header>
<h1>
<a href='/' onClick={function(event){
console.log(event);
event.preventDefault();
console.log('event in',this); //주체 App
this.setState({
mode:'welcome'
});
}.bind(this)}>
{this.state.subject.title}
</a>
</h1>
<p>{this.state.subject.sub}</p>
</header>
<TOC data={this.state.contents}></TOC>
<Content title={_title} desc={_desc}></Content>
</div>
);
}
}
export default App;
'Programming > 국비학원' 카테고리의 다른 글
220803 - 리액트 - update(기존 목록 내용 변경), delete(선택 목록 삭제) (0) | 2022.08.04 |
---|---|
2220802 - 리액트 - (Read) 메뉴 클릭 시 내용 표시 / (Create) 생성버튼 클릭 시 목록에 추가 (0) | 2022.08.03 |
220729 - React - 환경 구축 (0) | 2022.07.30 |
220728 - 제이쿼리 - 플러그인 제작 (0) | 2022.07.29 |
220727 - 제이쿼리 - 플러그인 (Masonry, bxslider, cookie) (0) | 2022.07.28 |