React TIL 구구단

장민우·2020년 11월 20일
1

https://www.youtube.com/channel/UCp-vBtwvBmDiGqjvLjChaJw 에서 공부한 내용

<html>
    <head>
        <meta charset="UTF-8" />
        <title>구구단</title>
        <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
        <!-- React.Component 사용  -->
        <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
        <!-- ReactDOM 사용 -->
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
        <!-- React.createElement를 써줄필요 없이 <클래스 or 함수명/>으로 렌더링 가능
        script 에 type = 'text/babel' 속성을 넣어 사용 -->
    </head>
    <body>
        <div id='root'></div>
        <script type = 'text/babel'>
            class GuGuDan extends React.Component {
                //constructor 생략 가능
                state = {
                    first : Math.ceil(Math.random() * 9),
                    second : Math.ceil(Math.random() * 9),
                    value : '',
                    result : '',
                }
                //변할것들은 모두 state를 이용

                onSubmitt = (e) =>{
                    //반드시 화살표 함수여야 한다 function을 쓸 경우 this값이 달라진다.
                    e.preventDefault();
                    //버튼을 눌렀을 때 이벤트 정지(화면 초기화)
                    //form 태그 안에서 제출하면 페이지가 새로고침 되는데 그 동작을 막는다.
                    if(parseInt(this.state.value) === this.state.first * this.state.second){
                        this.setState((prevState)=>{
                            return {
                                result :'정답 : ' + this.state.first * this.state.second,
                                //함수를 넣어줬을 때 prevState를 이용해 result값 변경
                                //result :'정답 : ' + prevState.value,
                                first : Math.ceil(Math.random()*9),
                                second : Math.ceil(Math.random()*9),
                                value : '',
                            }
                        });
                        //setState안에 함수를 넣어줘서 prevState란 변수속에 들어있는 이전 state값들을 사용할 수 있다.
                        //이전 값들을 이용해서 새로운 state를 만들 경우에는 setState에 함수를 넣어준다.
                        this.focusValue.focus();
                        //입력란에 버튼을 누르면 마우스 포인터가 사라지게 되는데 focus를 이용해서
                        //마우스 포인터를 사라지지 않게 한다.
                    }else{
                        this.setState({
                            result:'땡',
                            value:'',
                        })
                        this.focusValue.focus();
                    }
                };

                onChange = (e) =>{
                    this.setState({value : e.target.value})
                    //value값 실시간 변경
                };

                focusValue;

                render(){ 
                    // 화면에 바로 출력, setState할 때 render함수가 다시 실행된다.
                    // 만약 함수들을 밖으로 빼주지 않는다면 렌더링 할 때마다 함수가 실행되기 때문에
                    // 많은 낭비가 생긴다.
                    return (
                        <React.Fragment>
                        {/*CSS할 때 불편함 해소*/}
                            <div>{this.state.first} 곱하기 {this.state.second}?</div>
                            <form onSubmit={this.onSubmitt}>
                                {/*form안 버튼 기본이 submit*/}
                                {/*버튼을 눌렀을 때 this.onSubmit 함수 호출*/}
                                <input ref={(c)=>{ this.focusValue = c; }} type="number" value={this.state.value} onChange={this.onChange}/>
                                {/*onChange = 입력란에 숫자를 입력할 때마다 this.onChange 함수 호출*/} 
                                {/*DOM에 직접적으로 접근하고 싶을 때 ref를 이용*/}
                                {/*c는 해당 태그를 말한다. 여기서는 input태그*/}
                                {/*focusValue = document.querrySelector('input')*/}
                                <button>입력!</button>
                            </form>
                            <div>{this.state.result}</div>
                        </React.Fragment>
                    )
                }
            }
            //clss => className
            //for => htmlFor


        </script>
        <script type = 'text/babel'>
            ReactDOM.render(<div><GuGuDan /></div>, document.querySelector('#root'));
            //root태그에 GuGuDan 클래스 렌더링 
        </script>
    </body>
</html>

최근엔 Hooks를 이용을 권장.
많은 소스코드들이 class를 사용하고 있어서 반드시 공부해야 한다.
Hooks 사용

<html>  
    <head>
        <meta charset="UTF-8" />
        <title>구구단</title>
        <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
        <script 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>
    </head>
<body>
    <div id='root'></div>
    <script type ='text/babel'>

        const GuGuDan = () =>{
            const [first, setFirst] = React.useState(Math.ceil(Math.random()*9));
            const [second, setSecond] = React.useState(Math.ceil(Math.random()*9));
            const [value, setValue]= React.useState('');
            const [result, setResult] = React.useState('');
            //state를 선언하는 방법 React.useState 소괄호 안에 값 생성
            //1번째 인자들은 0번째 인자전용 setState
            //반드시 컴포넌트(GuGuDan)안에 넣어준다.
            const inputRef = React.useRef(null);
            //useRef를 이용해서 DOM에 접근

            const onSubmitForm = (e) =>{
                e.preventDefault();
                if(parseInt(value) === first * second){
                    setResult(value + '정답!');
                    setFirst(Math.ceil(Math.random() * 9));
                    setSecond(Math.ceil(Math.random() * 9));
                    setValue('');
                    inputRef.current.focus();
                }else{
                    setValue('');
                    setResult('땡!');
                    inputRef.current.focus();
                }
            }

            const onChangeForm = (e) =>{
                setValue(e.target.value);
            }

            return (
                <React.Fragment>
                    <div>{first} 곱하기 {second}?</div>
                    <form onSubmit={onSubmitForm}>
                        <input ref={inputRef} type='number' value={value} onChange={onChangeForm}/>
                        <button>버튼!</button>
                    </form>
                    <div>{result}</div>
                </React.Fragment>
            )
        }
        //Hooks는 state가 바뀔 때 마다 함수가 다시 실행하기 때문에 조금 더 느릴 수 있다.
    </script>
    <script type ='text/babel'>
        ReactDOM.render(<GuGuDan />, document.querySelector('#root'));
    </script>
</body>
</html>

0개의 댓글