[웹 게임을 만들며 배우는 React] 구구단 (컴포넌트, state, 데브툴즈, fragment, ref)

안지수·2023년 3월 6일
0
post-custom-banner

return 한 것이 화면임!!!

리액트에서 가장 기억할 것은
state는 변경되는 데이터이고, 변경은 renderreturn에 의해 화면에 나타남!! state에는 데이터가 들어간다.

😊 리액트를 왜 쓰는가

: 복잡한 웹, 앱을 쉽게 구현 가능하게 해줌, 데이터와 화면 일치 문제 구현 가능
-> 웹 브라우저는 html, css, js만 읽을 수 있음: 리액트도 결국 자바스크립트 임
-> 리액트는 데이터 중심으로 움직임!
-> 데이터(state) 바뀌면 화면 자동으로 바뀜
-> 우리가 만든 컴포넌트 이름은 반드시 대문자!
-> 화면에 보일 것들을 return 옆에 다 쓰기
-> 객체를 함부러 바꾸지 마라

😊 컴포넌트 (class 컴포넌트, fuction 컴포넌트-함수의 종류)

*컴포넌트: 데이터와 화면을 하나로 묶어놓은 덩어리
-> 요즘엔 거의 '함수 컴포넌트'를 사용
but!! 여전히 class 컴포넌트를 사용하는 곳도 있어서, 알아둘 것

1. class component


-> Like버튼을 클릭하였을 때, 그 부분의 내용이 바뀜! 데이터가 true로 바뀌는 즉시, 화면이 바뀜

2. 함수 component: 함수형 아님!!

<함수 표현 방법>

  • 함수 선언식:

  • 함수 표현식:

  • 화살표 함수:

    -> 함수 선언 식에서, fuction 과 함수 이름 지우고, return 지워!! => 넣고!!

const sum = (num1, num2)=>num1+num2;

const result = sum(10, 20);
console.log(result)

-> 식별자 없으므로, 함수 호출을 위해선 함수 표현식 방법으로!

-> 매개변수가 하나일 경우 소괄호도 제거 가능

-> 매개변수가 없을 경우, 위와 같이 소괄호만 적으면 됨

-> 함수에서 객체를 반환하는 경우에는, 소괄호로 한 번 더 묶어줘서 객체임을 나타내줘야 함.

  • 내부 함수: 함수 안에 함수가 들어가 있는 형태

<함수 component>

-> liked가 true이면 실행, 아니면 버튼 보여줌. (함수 컴포넌트에서는 this 쓸 일 없음)

😊 컴포넌트를 화면에 그리기 위한 2가지 버젼 (17, 18)

-> 회사에 들어가면 17 버전인지 (render인지) 18버전인지 구분해야함 (아직 회사의 많은 부분들이 17버젼으로 되어있음)
1. 17버젼

2. 18버젼

😊 가독성을 위한 JSX

: js에 XML을 추가한 확장형 문법
-> js는 jsx를 인식하지 못하므로, babel 패키지를 통해 변환해 주어야 함 (아래코드 추가해주어야 함)

<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>


-> JS에 XML 사용 함.
** onclick은 함수 자리여서, 다음과 같이 화살표 함수로 적어줘야 함!!


-> return에는 태그가 하나만 와야 해서, 위와 같이 형제 태그들은 하나의 부모태그로 묶어주어야 함.


-> 컴포넌트도 여러 번 쓰일 수 있음

HTML과 XML의 차이

  • HTML: 데이터의 표현이 목적, 정해진 태그 사용, 웹 브라우저가 있어야 실행 가능
  • XML: 데이터 교환이 목적, 사용자가 태그를 정의해서 사용 가능(title 태그가 html과 달리 특정 역할이 있지 않음- 입맛에 따라 사용하면 됨), 특정 환경에 구애 받지 않음

!리액트에서 태그는 항상 소문자로, 컴포넌트대문자

!싱글 태그에서 닫는 태그 꼭

!js코드 부분은 중괄호로! 객체면 중괄호 2개

-> if문 대신 삼항연산자 {}
-> for문 대신 배열 자주 사용 (map이용해서)

😊 데브툴즈 (react developer tools)

: 데이터와 화면 한 번에 볼 수 있도록 하는 크롬 확장 프로그램- 렌더링을 직접 눈으로 확인하기 위함- 렌더링이 언제 발생하는 지 알아두고 자원 낭비를 방지하기 위해서)
--> 데이터의 변화에 따른 화면 변화 동시에 확인하기 위한 크롬 확장 프로그램

-> state 먼저 바뀌고(데이터), 화면이 바뀌는 게 맞음!! (but,데브툴즈가 한 박자 느림)

😊 구구단 리액트로 만들기

<전체 코드>

<html>
<head>
    <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
    <meta charset="UTF-8"/>
    <title>구구단</title>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
    class GuGuDan extends React.Component{ //구구단이라는 class 컴포넌트 하나 만들고
        /*constructor(props){
            super(props); //constructor는 안써도 됨 (this도 빼고)
            this.state={ //객체 안에다가 바뀌는 것들을 속성으로 추가해주기 (바뀌는 부분-state: 숫자, input, 결과부분)- 바뀌어야 될 부분 여러 개이면 객체로!!
                first: Math.ceil(Math.random()*9), //랜덤값
                second: Math.ceil(Math.random()*9), //랜덤값
                value: '',
                result: '',
            };
        }*/
        state={ //객체 안에다가 바뀌는 것들을 속성으로 추가해주기 (바뀌는 부분-state: 숫자, input, 결과부분)- 바뀌어야 될 부분 여러 개이면 객체로!!, 이게 실무에서 훨씬 많이 쓰임
            first: Math.ceil(Math.random()*9), //랜덤값
            second: Math.ceil(Math.random()*9), //랜덤값
            value: '',
            result: '',
        };

        //이렇게 함수처럼 따로 빼서 써도됨- 이땐 무조건 화살표 함수로!(this가 애매해줘서)- setState할 때마다(렌더링할 때 마다) render새로 실행 되어서, render안의 힘수 계속 새로 생김
        onSubmit = (e) => { //form submit 했을 때 어떻게 되는지 (입력누르면 onSubmit 실행)
                        e.preventDefault();
                        if (parseInt(this.state.value)===this.state.first * this.state.second){
                            this.setState( (prevState) => {  //예전 state 값을 현재 state 값으로 만들 때는, 이처럼 return 해주는 함수로!! (객체, 함수 쓸 때 구분)
                                return{
                                    result: this.state.first + 'X' + this.state.second + '=' + prevState.value + '정답!',
                                    first: Math.ceil(Math.random()*9), //랜덤값
                                    second: Math.ceil(Math.random()*9), //랜덤값
                                    //value는 다시 비워져야 함
                                    value: '',
                                };
                            });
                            this.input.focus(); //계속 깜박 거리게
                        }
                        else{
                            this.setState({
                                result: '땡',
                                value: '',
                            });
                        }
                        this.input.focus(); //계속 깜박 거리게
        };

        onChange = (e) => {
            this.setState({ value: e.target.value});
        }
        
        onRefInput = (c) => { this.input = c; }
        
        input;

        //컨텐츠
        render(){//render는 화살표 함수 안써도됨
            //결괏값 태그로 return
            //태그 사이에 {}중괄호 넣으면, 중괄호에는 js를 넣을 수
            //jsx에서는 싱글 태그에 닫는 태그를 꼭 항상 넣어줘야함!!!!!!
            //state 바꿀 때는 setState!
            //e는 이벤트 객체를 의미
            return ( //쓸데 없는 div를 없애고 공백으로 써도 됨-babel이 지원하지 않음(babel 2가 지원), 오류나면 'React.Fragment' 써주면 됨, 소괄호 없어도 됨(그룹연산자)
                <React.Fragment> 
                    <div>{this.state.first}곱하기{this.state.second}?</div>  
                    <form onSubmit={this.onSubmit}>
                        <input ref={this.onRefInput} type="number" value={this.state.value} onChange={this.onChange} />
                        <button type="submit">입력!</button>
                    </form>
                    <div>{this.state.result}</div>
                </React.Fragment>
            ); 
        }
    }
</script>
<script type="text/babel">
    ReactDOM.render(<div><GuGuDan /><GuGuDan /><GuGuDan /></div>, document.querySelector('#root')); //그 컴포넌트를 화면에 그리겠다
</script>
</body>
</html>


-> 바뀌어야 할 부분 (state): 문제 부분 숫자 2개, input창, 결과 부분

-> 태그 속에 js 쓰기 위해서는 중괄호 써야 함 : {}, 객체도 중괄호!
-> state 바꿀 때는 setState 써주기, 안바뀌는 부분은 그냥 태그로!! (수동으로 바꿀 값들만 state로)
onChange 이벤트: 입력이 끝났을 때 발생하는 이벤트
onInput: input 태그 안의 값들이 변경될 때 마다 수행
*onSubmit: 입력이 되어 제출되면 실행되는 이벤트

-> e는 이벤트 객체를 의미함 (이벤트 발생 시, 정보가 이벤트 객체에 저장 됨)

😊 fragment와 기타 팁들

-> 함수를 따로 뺏을 경우, 직접 함수를 만들어줬을 경우 무조건 화살표 함수로!!!!
-> render 안에서 쓴 경우에는 화살표 함수로 안 써도 됨

-> return에서 첫 'div'태그는 불필요하다. 따라서 이를 없애기 위해서는, React.Fragment로 대체 할 수 있음!

😊 ref

: DOM에 직접 접근하기 위한 리액트 문법 (HTML에서의 id와 같은 역할)
*HTML 에서 특정 아이디를 가진 태그에만 스타일을 따로 적용하거나 하기 위해,

-> 와 같이 작성한다. 리액트에서 id와 같은 역할이 ref!!

만약, 값 입력 때마다 input에 포커스를 주고 싶다면? (계속 깜박거리게)



: ref~ 그 코드 외우기 (입력되도 포커스 풀리지 않게)

-> input 태그 속성에 직접 접근

-> setState()하면 render()가 수행됨
: 따라서 render수행 될 때마다 함수 새로 만들어지면 너무 자원 낭비이므로, 함수를 따로 밖으로 빼내는 것이 효율적임! (화살표 함수로)




** 리액트 감 잡는 법: 아무 웹 사이트에서 state를 찾아!!! (즉, 바뀌는 데이터 부분) 즉, 리액트는 바뀌는 부분만을 렌더링 하기 위한 좋은 라이브러리임!!!

⭕ 전체 코드들은 아래 깃허브 링크 참조!
https://github.com/An-jisu/React

profile
지수의 취준, 개발일기
post-custom-banner

0개의 댓글