리액트란 ?
페이스북에서 만든 프레임워크, React
사용자 인터페이스를 구축하기 위한 효율적이고 유연한 JavaScript Framework (또는 Library라고 하는 경우도 있음)
Component 라는 작은 코드의 파편을 이용하여 복잡한 UI를 구성
기존 Html, CSS, JavaScript 로 화면을 만들 때 복잡해서 JavaScript 만으로 화면을 꾸미는 게 -> 리액트
리액트는 페이지를 컴포넌트, Components라는 것으로 만든다. { } 대괄호를 많이쓰는 문법이어서 어디에 코드를 쓰고 있는지 주의해야 한다.
장점 : HTML, CSS, JS 따로 따로 만들지 않아도 된다.
단점 : JS의 코드가 난잡해질 수 있다. -> html형태로 생긴 명령어를 만들어 html을 표현하여 보완됨
리액트를 공부하는 방법 : 공식 문서에 게임 만들기 -> 일단 따라쓰면서 충분히 익혀두기! ↓↓
https://ko.reactjs.org/tutorial/tutorial.html
CDN 링크
1. 개발용 - 오늘 학습용으로 사용할 링크 !
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
2. 배포용
<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
Babel 링크까지 연습할 때 사용할 script link ↘
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
React 시작해보기 - reactDOM을 사용하여 메세지 띄워보기
1. html에 위의 react 개발용 코드 삽입
- 첫 번째 script 는 react를 사용하기 위해 꼭 필요
- 두 번째 script 는 reactDOM과 관련된 듯! ?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
</head>
<body>
</body>
</html>
2. ReactDOM.render() / React.createElement()
* render()
render의 첫 번째 인자값 : 넣을 내용
render의 두 번째 인자값 : 내용을 넣을 위치
ReactDOM.render(내용, 위치)
* React.createElement()
createElement의 첫 번째 인자값 : 요소 Element
createElement의 두 번째 인자값 : style, onclick과 같은 설정
createElement의 세 번째 인자값 : 내용(innderHTML)
<body>
<div id="root"></div> <!-- 보통 root 입력 ! -->
<script type="text/javascript">
ReactDOM.render(
React.createElement('button',null,'버튼'), // 내용
document.querySelector('#root') // 위치
)
</script>
</body>
위의 코드는 실무적이기보다 학습 용도 !
Class 시작해보기 class 사용하여 component 만들기
component를 만들기 위해서는 function과 class 두 방법이 있다. 일단 class로 공부해보기 -> 나중에는 함수로 구현하게 될 것!
1. class 사용해서 Component 만드는 기본 구조
Component명의 첫 글자는 항상 대문자 ! ex) LoginBtn
<script type="text/javascript">
class LoginBtn extends React.Component{ // class LoginBtn 이라는 Component 만들기
constructor(props){
super(props)
}
render(){ // LoginBtn class가 return하는 값
return(
React.createElement('button', null, '로그인')
)
}
}
ReactDOM.render(
React.createElement(LoginBtn), // class명 입력
document.querySelector('#root')
)
</script>
2. button에 event 주기
html의 경우 onclick = "alert('안뇽')" 이런 식이었지만 React 문법은 조금 다르다 !
render(){
return(
React.createElement('button', {onClick:()=>{alert('로그인버튼을 눌렀습니까')}}, '로그인')
)
}
createElement()의 설정인 두 번째 인자값에
{onClick:()=>{alert('로그인버튼을 눌렀습니까')}}
요렇게 추가하면 된다. onClick -> camel 표기법 주의 **
3. button 로그인 -> 로그아웃 -> 로그인 클릭마다 바뀌게 만들기
-> 인스타그램의 좋아요 카운팅 등에 적용할 수 있음
<body>
<div id="root"></div>
<script type="text/javascript">
class LoginBtn extends React.Component{
constructor(props){
super(props)
this.state={
isLogin : false
}
}
render(){
return(
React.createElement('button',
{onClick:()=>{ this.setState({isLogin:!this.state.isLogin}) }},
this.state.isLogin ? '로그아웃' : '로그인')
)
}
}
ReactDOM.render(
React.createElement(LoginBtn),
document.querySelector('#root')
)
</script>
</body>
LoginBtn class의 return 값을 아래처럼 바꿨다.
React.createElement('button', {onClick:()=>{this.setState({isLogin:!this.state.isLogin}) }}, this.state.isLogin ? '로그아웃' : '로그인')
createElement의 첫 번째 인자값 : 요소 : 'button'
'button'
두 번째 인자값 : 설정값 - onClick 으로 this 해당 요소의 state 상태를 set 설정한다 -> isLogin 은 this. 해당 요소의 state 상태의 isLogin 값(boolean)을 ! 기호를 사용해 반대로 바꿔준다.
{onClick:()=>{this.setState({isLogin:!this.state.isLogin}) }}
세 번째 인자값 : 내용 - 삼항 연산자로 isLogin 이 true 일 때 '로그아웃', false 일 때 '로그인' 이 표시되도록 한다.
this.state.isLogin ? '로그아웃' : '로그인')
JSX 시작해보기 JavaScript + XML = JSX
XML : 예전에 데이터를 주고 받을 때 씀
ex) <name>ingoo</name> 요런 방식으로 name을 두 번 써야함 -> 비효율적
json : 요즘 거의 쓰이는 데이터 주고 받는 형식
ex) {name : 'ingoo'}
XML 을 쓸 때 코드를 닫아주는 ( />) 것이 중요했어서 현재의 JSX도 닫아주는 게 있다.
class 명 : Hello Component를 사용할 때 <Hello> 이렇게 쓰면 오류 -> <Hello/> '/'슬래쉬까지 써서 닫아야 오류 X
JSX 공부하기 전 중요한 점 : JSX 는 html 언어가 아닌 JavaScript 언어이다.
0. JS html 쓰는 라이브러리 설치 / babel로 변경
react CDN - 아래 코드를 html에 삽입
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
+ script type="text/javascript" 에서 --> babel 로 변경
<script type="text/babel">
1. 위의 코드를 JSX 를 사용해서 표현하기
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React연습</title>
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class LoginBtn extends React.Component{
constructor(props){
super(props)
this.state={
isLogin : false
}
}
render(){
return(
// React.createElement('button',
// {onClick:()=>{ this.setState({isLogin:!this.state.isLogin}) }},
// this.state.isLogin ? '로그아웃' : '로그인')
<button onClick={()=>{this.setState({isLogin:!this.state.isLogin}) }}>
{this.state.isLogin ? '로그아웃' : '로그인'}
</button>
)
}
}
ReactDOM.render(
//React.createElement(LoginBtn)
<LoginBtn/>,
document.querySelector('#root')
)
</script>
</body>
</html>
JSX 를 써서 달라진 점
1. React.createElement('button', 설정, 내용) -------> <button ~~~~> </button>
2. React.createElement의 설정 부분 --------> onClick={()=>{this.setState({isLogin:!this.state.isLogin}) }}
- {onClick:{()=>{} } } 에서 onClick = {()=> {~}} 으로 onClick이 대괄호 {} 밖으로 나오고 : -> = 로 수정됨
3. React.createElement의 내용 부분 -------> { } 대괄호로 감싸기
- 감싸지않으면 text로 처리가 됨
4. ReactDOM.render(내용 , 위치) 중 내용을 React.createElement( className) ---> <className /> 으로 변경
결과물은 위에 JSX 를 쓰지않은 코드와 결과물과 똑같이 나온다.
로그인 ---Click ---> 로그아웃
로그아웃 ----Click --->로그인
DOM & STATE 1초마다 변하는 시간 표현하기
1. HTML & JavaScript 의 경우의 코드 만들어보기 (비교 위함)
<body>
<div id="root"></div>
<script type="text/javascript">
function tiktok(){
const div = document.createElement('div')
const h1 = document.createElement('h1')
const h2 = document.createElement('h2')
let day = "It's Monday";
let time = new Date().toLocaleTimeString();
h1.innerHTML=day;
h2.innerHTML=time;
div.appendChild(h1);
div.appendChild(h2);
document.querySelector('#root').innerHTML=div.innerHTML;
}
setInterval(tiktok, 1000)
</script>
</body>
1초 마다 1초씩 올라간다.
하지만 이 경우 Elements를 보면 1초에 한 번씩 div id ="root" 안의 h1, h2 까지 전부 변경된다. JSX로 원하는 곳만 변경되게 만들기 ↓↓↓
2. React 기본 코드 & Tiktok class 작성
<div id="root"></div>
<script type="text/babel">
class Tiktok extends React.Component{
constructor(props){
super(props)
}
render(){
return(
)
}
}
ReactDOM.render(
<Tiktok/>,
document.querySelector('#root')
)
</script>
3. return 값 html 형식으로 주기
class Tiktok extends React.Component{
constructor(props){
super(props)
this.state={
time : new Date().toLocaleTimeString()
}
}
render(){
return(
<div>
<h1>It's Monday</h1>
<h2>It's {this.state.time}</h2>
</div>
)
}
}
ReactDOM.render(
<Tiktok/>,
document.querySelector('#root')
)
4. setInterval 추가 - 1초마다 this.state.time 을 현재 시간으로 계속 설정(set) 해줌
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React연습</title>
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class Tiktok extends React.Component{
constructor(props){
super(props)
this.state={
time : new Date().toLocaleTimeString()
}
}
render(){
setInterval(()=>{
this.setState({time:new Date().toLocaleTimeString()})
},1000)
return(
<div>
<h1>It's Monday</h1>
<h2>It's {this.state.time}</h2>
</div>
)
}
}
ReactDOM.render(
<Tiktok/>,
document.querySelector('#root')
)
</script>
</body>
</html>
React JSX 로 하면 좋은 점 :
JavaScript 와는 다르게 h2 하나만 변경이 된다 !
React-> html & class 비교해서 다른 부분만 바꿔준다
(DOM의 역할)
ex) 페이스북의 누군가 글쓰면 바로 피드 올라오는 기능
JavaScript도 왼쪽처럼 만들 수 있지만 엄청난 노가다가 필요하다.
질문 2
* 아래처럼 this.state 없이 설정하고 render() 다음 1초마다 this.setState({}) 를 수행하게 만들어도 1초마다 시간이 변한다. (대신 return 부분에 this.state.time 변수 대신 new Date()로 들어가야함) - setState({}) 에서 {} 대괄호를 빼면 멈춤!
class Tictok extends React.Component{
constructor(props){
super(props)
}
render(){
setInterval(()=>{
this.setState({})
},1000)
return(
<div>
<h1>It's Monday</h1>
<h2>It's{new Date().toLocaleTimeString()}</h2>
</div>
)
}
}
Components 두 개 이상 만들어 보기
1. html 준비
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React연습</title>
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
</script>
</body>
</html>
2. World 를 return하는 World 라는 class 만들기
<div id="root"></div>
<script type="text/babel">
class World extends React.Component{
// 설정 생략 가능
render(){
return(
<div>
World
</div>
)
}
}
ReactDOM.render(
<World/>,
document.querySelector('#root')
)
</script>
div를 굳이 쓴 이유는 class 명이 World로 똑같아서 겹침 방지로 <> 빈 tag 라도 넣어 준다 !
3. Hello를 return 하는 class Hello 만들기 + 해당 Component를 World에 넣기
class Hello extends React.Component{
render(){
return(
<>
Hello
</>
)
}
}
class World extends React.Component{
// 설정 생략 가능
render(){
return(
<div>
<Hello/> World
</div>
)
}
}
ReactDOM.render(
<World/>,
document.querySelector('#root')
)
4. App 이라는 class에 Hello, World components 를 넣어서 표현해보기
class Hello extends React.Component{
render(){
return(
<>
Hello
</>
)
}
}
class World extends React.Component{
// 설정 생략 가능
render(){
return(
<>
World
</>
)
}
}
class App extends React.Component{
render(){
return(
<div>
<Hello/> <World/>
</div>
)
}
}
ReactDOM.render(
<App/>,
document.querySelector('#root')
)
5. 변수를 추가해서 변수 값 출력해보기
class App extends React.Component{
render(){
const hi = <h1>안녕</h1>
const ha = <h1>하세요!</h1>
return(
<div>
{hi}{ha}<Hello/> <World/>
</div>
)
}
}
{ } 대괄호로 변수를 감싸서 표현해야한다. { } 이 없는 경우 hi ha 가 그대로 text로 return 된다.
수업 끗 실습 시작
실습 : 아래 html 코드를 JSX Components 사용해서 표현해보기 (html, css 제공됨)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>리액트 시간</title>
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<link rel="stylesheet" href="./0628.css">
</head>
<body>
<div id="root">
<!--
<ul class="comment">
<li>
<ul class="comment-row">
<li class="comment-id">web7722</li>
<li class="comment-content">안녕하세요 방가</li>
<li class="comment-date">20221-06-28</li>
</ul>
</li>
<li>
<ul class="comment-row">
<li class="comment-id">web7722</li>
<li class="comment-content">안녕하세요 방가</li>
<li class="comment-date">20221-06-28</li>
</ul>
</li>
<li>
<ul class="comment-row">
<li class="comment-id">web7722</li>
<li class="comment-content">안녕하세요 방가</li>
<li class="comment-date">20221-06-28</li>
</ul>
</li>
<li class="comment-form">
<form>
<h4>댓글쓰기 <span>(3)</span></h4>
<span class="ps_box">
<input type="text" placeholder="댓글내용을 입력해주세요." class="int"/>
</span>
<input type="submit" value="등록" class="btn"/>
</form>
</li>
</ul>
-->
</div>
<script type="text/babel">
class ComponentForm extends React.Component{
redner(){
return ;
}
}
class ComponentRow extends React.Component{
render(){
return ;
}
}
class CommentApp extends React.Component{
render(){
return(
<ul className="comment">
<li>
<ul className="comment-row">
<li className="comment-id">web7722</li>
<li className="comment-content">안녕하세요 방가</li>
<li className="comment-date">20221-06-28</li>
</ul>
</li>
<li>
<ul className="comment-row">
<li className="comment-id">web7722</li>
<li className="comment-content">안녕하세요 방가</li>
<li className="comment-date">20221-06-28</li>
</ul>
</li>
<li>
<ul className="comment-row">
<li className="comment-id">web7722</li>
<li className="comment-content">안녕하세요 방가</li>
<li className="comment-date">20221-06-28</li>
</ul>
</li>
<li className="comment-form">
<form>
<h4>댓글쓰기 <span>(3)</span></h4>
<span className="ps_box">
<input type="text" placeholder="댓글내용을 입력해주세요." className="int"/>
</span>
<input type="submit" value="등록" className="btn"/>
</form>
</li>
</ul>
)
}
}
ReactDOM.render(
<CommentApp />,
document.querySelector('#root')
)
</script>
</body>
</html>
css
*{margin:0; padding:0;}
body{
font-family: 'Noto Sans KR', sans-serif;
font-weight:300;
}
ul,li{
list-style:none;
}
.comment{
display:flex;
flex-direction: column;
flex-wrap: nowrap;
padding:30px;
width:600px;
margin:0 auto;
}
.comment > li{ margin-top:20px; }
.comment > li:nth-child(1){ margin:0px;}
.comment-row{
display:flex;
justify-content: space-between;
flex-direction: row;
}
.comment-row{
margin-top:20px;
width:100%;
}
.comment-row > li:nth-child(2){
flex-shrink: 0;
flex-grow: 1;
padding-left:25px;
z-index:1;
width:100%;
}
.comment-row > li:nth-child(2){
width:85px;
}
.comment-form > form{
display:flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
}
.comment-form > form > h4{
width:100%;
margin:14px 0 14px 0;
}
.comment-content{
word-break:break-all;
padding-right:25px;
}
.ps_box{
display: block;
position: relative;
width: 80%;
height: 51px;
border: solid 1px #dadada;
padding: 10px 14px 10px 14px;
background: #fff;
box-sizing: border-box;
}
.ps_box > input{
outline:none;
}
.int{
display: block;
position: relative;
width: 100%;
height: 29px;
padding-right: 25px;
line-height: 29px;
border: none;
background: #fff;
font-size: 15px;
box-sizing: border-box;
z-index: 10;
}
.btn{
width:18%;
padding: 18px 0 16px;
text-align: center;
box-sizing: border-box;
text-decoration: none;
border:none;
background:#333;
color:#fff;
font-size:14px;
}
.comment-delete-btn{
display:inline-block;
margin-left:7px;
cursor: pointer;
}
.comment-update-input{
border:none;
border-bottom: 1px solid #333;
font-size:16px;
color:#666;
outline: none;
}
정답 :
<script type="text/babel">
class ComponentForm extends React.Component {
render() {
return (
<form>
<h4>댓글쓰기 <span>(3)</span></h4>
<span className="ps_box">
<input type="text" placeholder="댓글내용을 입력해주세요." className="int" />
</span>
<input type="submit" value="등록" className="btn" />
</form>
)
}
}
class ComponentRow extends React.Component {
render() {
return (
<li>
<ul className="comment-row">
<li className="comment-id">web7722</li>
<li className="comment-content">안녕하세요 방가</li>
<li className="comment-date">20221-06-28</li>
</ul>
</li>
)
}
}
class CommentApp extends React.Component {
render() {
return (
<ul className="comment">
<li className="comment-form">
<ComponentForm/>
<ComponentRow/>
<ComponentRow/>
<ComponentRow/>
</li>
</ul>
)
}
}
ReactDOM.render(
<CommentApp />,
document.querySelector('#root')
)
질문 1 : class / constructor(props) / super(props)
class LoginBtn extends React.Component{
constructor(props){
super(props)
}
}
질문 2 : 위에 !
'블록체인 기반 핀테크 및 응용 SW개발자 양성과정 일기' 카테고리의 다른 글
[75일차 복습] React, state 끌어 올리기 / 리액트 구구단 (0) | 2021.06.29 |
---|---|
[75일차] 20210629 React 리액트 구구단 출력하기 (0) | 2021.06.29 |
[74일차] 20210628 리액트 react - JSX, ReactDOM (0) | 2021.06.28 |
[69~73일차] 20210621~25 apple clone 팀 프로젝트 (0) | 2021.06.21 |
[64~68일차] 20210613~17 apple clone 팀프로젝트 (0) | 2021.06.14 |