본문 바로가기

블록체인 기반 핀테크 및 응용 SW개발자 양성과정 일기

[74일차 복습] 리액트란? 리액트 기초 배우기 / React CDN 링크

반응형

리액트란 ? 

페이스북에서 만든 프레임워크, React 

사용자 인터페이스를 구축하기 위한 효율적이고 유연한 JavaScript Framework (또는 Library라고 하는 경우도 있음)

Component 라는 작은 코드의 파편을 이용하여 복잡한 UI를 구성 

기존 Html, CSS, JavaScript 로 화면을 만들 때 복잡해서 JavaScript 만으로 화면을 꾸미는 게 -> 리액트 

리액트는 페이지를 컴포넌트, Components라는 것으로 만든다. { } 대괄호를 많이쓰는 문법이어서 어디에 코드를 쓰고 있는지 주의해야 한다. 

 

장점 : HTML, CSS, JS 따로 따로 만들지 않아도 된다.

단점 : JS의 코드가 난잡해질 수 있다. -> html형태로 생긴 명령어를 만들어 html을 표현하여 보완됨

 

 

 

 

리액트를 공부하는 방법 : 공식 문서에 게임 만들기 -> 일단 따라쓰면서 충분히 익혀두기! ↓↓

https://ko.reactjs.org/tutorial/tutorial.html

 

자습서: React 시작하기 – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

 

 

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  : 위에 ! 

 

반응형