React 스터디 1주차
🎮 웹 게임을 만들며 배우는 React
1주차: 구구단
1. React를 쓰는 이유?
사용자 인터페이스 및 양질의 사용자 경험을 제공할 수 있으며 싱글 페이지 애플리케이션(SPA), 즉 한 개의 페이지로 이루어진 애플리케이션을 만드는 데 용이하다. 또한, 데이터와 화면의 일치를 리액트가 자동으로 도와준다. 마지막으로 중복되는 컴포넌트를 하나로 묶어주는 것이 가능하여 유지보수가 편리하다는 장점 또한 있다.
2. 컴포넌트 생성
코드가 비효율적으로 느껴질 수 있으나, 이는 리액트의 동작 원리를 알아보기 위함이다.
https://ko.reactjs.org/docs/cdn-links.html 에서 CDN 링크를 가져왔다.
이때
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>이는 react가 동작하기 위한 핵심적인 파일이 들어 있는 자바스크립트이며
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>이 react-dom은 리액트 코드를 웹에 붙여주는 역할이라고 이해하면 된다.
<!DOCTYPE html>
<html>
    <head>
        <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>
        <body>
            <div id="root"></div> <!-- 결과: <div id="root"><button>Like</button></div> -->
            <script> 
                const e = React.createElement;
                
                class LikeButton extends React.Component {
                    constructor(props) {
                        super(props);
                    }
                    render() {
                        // LikeButton을 화면에 어떻게 표시할 것인지
                        return e('button', null, 'Like'); // <button>Like</button>을 만들겠다!
                    }
                }
            </script>
            <script>
                ReactDOM.render(e(LikeButton), document.querySelector('#root')); // 컴포넌트를 root 내에 그림
            </script>
        </body>
    </head>
</html>
예측한대로 button이 생성되었다!
이때 button에 onClick 속성을 부여해 보자. (이때 Html의 속성을 JS로 표현할 시에는 Camel Case를 이용해야 한다.)
                    render() {
                        // LikeButton을 화면에 어떻게 표시할 것인지
                        return e('button', {onClick: () => {console.log('clicked')}, type: 'submit'}, 'Like'); // <button>Like</button>을 만들겠다!
                    }
개발자 도구의 콘솔 로그에 clicked가 남는다.
이제 상태(state)를 변경해 보자. 이때 상태는 바뀌는 부분, 또는 바뀔 수 있는 부분을 의미한다. 버튼을 클릭하면 Like를 Liked로 변경하자.
                    constructor(props) {
                        super(props);
                        this.state = { 
                            // 상태
                            liked: false,
                        };
                    }
                    render() {
                        // LikeButton을 화면에 어떻게 표시할 것인지
                        return e('button', {onClick: () => {this.setState({ liked: true })}, type: 'submit'}, 
                            this.state.liked === true ? 'Liked' : 'Like',); // <button>Like</button>을 만들겠다!
                    }
                }
클릭 시에 상태에 따라 Like가 Liked로 변한다. 상태를 데이터라고 가정했을 시에 데이터를 화면에 보여주는 것의 예시라 할 수 있다.
3.JSX와 바벨(babel)
최신 문법 등을 JS에서 사용할 수 있게 해 주는 babel을 이용한다.
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>그러면 다음과 같이 JS 내에서 html 태그 문법의 사용이 가능하다.
                    render() {
                        // LikeButton을 화면에 어떻게 표시할 것인지
                        return <button type="submit" onClick={() =>{this.setState({ liked: true })}}>
                        	{this.state.liked === true ? 'Liked' : 'Like'}
                        </button>
                        // JSX
                    }
                }
            </script>
            <script>
                ReactDOM.render(<LikeButton />), document.querySelector('#root')); // 컴포넌트를 root 내에 그림
            </script>이때 JSX라는 개념이 등장하는데, 이 JSX는 JS + XML의 개념이라고 한다.
4. 구구단
        <body>
            <div id="root"></div> <!-- 결과: <div id="root"><button>Like</button></div> -->
            <script type="text/babel"> 
                class GuGudan extends React.Component {
                    constructor(props) {
                        super(props);
                        this.state = { 
                            // 바뀌는 것들
                            first: Math.ceil(Math.random() * 9),
                            second: Math.ceil(Math.random() * 9),
                            value: '',
                            result: '',
                        };
                    }
                    
                    onSubmit = (e) => {
                        e.preventDefault();
                        if(parseInt(this.state.value) === this.state.first * this.state.second) {
                            this.setState ({
                                result: '정답!',
                                first: Math.ceil(Math.random() * 9),
                                second: Math.ceil(Math.random() * 9),
                                value: '',
                            });
                        }
                        else {
                             this.setState({
                                result: '땡!',
                                value: '',
                        })  
                        }
                    };
                    onChange = (e) => {
                        this.setState({ value: e.target.value })
                    };
                    render() {
                        return (
                            <div>
                                <div> {this.state.first} 곱하기 {this.state.second}은? </div>
                                <form onSubmit={this.onSubmit}> 
                                    <input type="number" value={this.state.value} 
                                        onChange={this.onChange}/>
                                    <button>입력!</button>
                                </form>
                                <div>{this.state.result}</div>
                            </div>
                        );
                    }
                } 
            </script>
            <script type="text/babel">
                ReactDOM.render((<GuGudan />), document.querySelector('#root')); // 컴포넌트를 root 내에 그림
            </script>
        </body>
+)

이때

이와 같이 쓸데없는 div를 없애고 <>...</> 만으로 처리할 수 있다.
++)

constructor... 부분을 제외하고, state만 선언해서 사용하는 것이 가능하다.
+++)
이전의 상태를 표현할 시에는 다음과 같다.
                        if(parseInt(this.state.value) === this.state.first * this.state.second) {
                            this.setState ((prevState) => { // 이전 상태 표현
                                return {
                                result: prevState.first + ' X ' + prevState.second + ' = ' + prevState.value + ' 정답! ',
                                first: Math.ceil(Math.random() * 9),
                                second: Math.ceil(Math.random() * 9),
                                value: '',
                            }
                            });
                        }
                        // 이전 state로 새로운 state 값을 만들 때에는 return을 사용++++)
입력 후 focus를 주려면 다음과 같다.
                        if(parseInt(this.state.value) === this.state.first * this.state.second) {
                            this.setState ((prevState) => { // 이전 상태 표현
                                return {
                                result: prevState.first + ' X ' + prevState.second + ' = ' + prevState.value + ' 정답! ',
                                first: Math.ceil(Math.random() * 9),
                                second: Math.ceil(Math.random() * 9),
                                value: '',
                            }
                            });
                            this.input.focus();
                        }
                        // 이전 state로 새로운 state 값을 만들 때에는 return을 사용
                        else {
                             this.setState({
                                result: '땡!',
                                value: '',
                        })  
                             this.input.focus();
                        }
                    };
                    onChange = (e) => {
                        this.setState({ value: e.target.value })
                    };
                    input; 
                    onRefInput = (c) => { this.input = c; }; 
                    // state가 바뀔 때마다 render가 실행되므로 함수를 바깥에 선언하는 것이 좋다.
 
                    render() {
                        return ( 
                            <>
                                <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}/>추가
1.

3번 항목을 수강하던 도중 이와 같은 오류가 발생했다. element를 읽을 수 없어 발생하는 오류라고 한다.

ReactDOM.render 뒤에 괄호가 빠져 있었다. 😥
2.
1.7강 과제

{...}
result: this.state.first + ' X ' + this.state.second + ' = ' + this.state.value + ' 정답! ',
{...}📖 이용 강의
https://inf.run/gcb2 웹 게임을 만들며 배우는 React
Author And Source
이 문제에 관하여(React 스터디 1주차), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@artian99/React-스터디-1주차저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
                                
                                
                                
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)