1. 구조분해 할당으로 state, props 간편하게 사용하기

onSubmitForm = e => {
	const {result, value, tries,answer} = this.state;
 	...
}

render(){
	const {result, value, tries} = this.state;
    ...
}

NumberBaseball.js

const {index, value} = this.props;

Try.js

2. class 밖으로 뺄 수 있는 함수

this를 사용하지 않으면 class 밖으로 뺄 수 있다. (getNumbers 처럼)

 

리액트에서 state를 직접 바꾸는건 금지!

리랜더해주는 조건이 예전 state와 현재 state가 달라야 리랜더를 해주는데 직접 바꿔버리면 달라지지 않는다.

그래서 불변성을 잘 지켜야함. 

특히 객체나 배열! 주의

tries: [...tries, `${this.state.value}: 홈런!`],

-기존 배열을 유지시켜주고 싶다면 spred 연산자를 사용해주면 좋다.

-this.state.tries[0] = 10;, this.state.tires.push(20);      <----이런식으로 하면 안됌!!

 

직접 만든 전체코드

import React, {Component} from "react";
import Try from "./try";

//숫자 내게 랜덤으로 뽑기 함수
function getNumbers(){
    const numbers = new Array(9).fill(0).map((v,i)=>v+i+1);
    const shuffle = [];
    while(numbers.length > 0){
        const rand = Math.floor(Math.random() * numbers.length);
        const number = numbers.splice(rand,1)[0];
        shuffle.push(number);
    }
    console.log(shuffle);
    return shuffle.slice(0,4);
}


class NumberBaseball extends Component{
    state = {
        value:'',
        result:'',
        answer : getNumbers(),
        tries:[],
    }
    onChangeInput = e => {
        const value = e.target.value;
        this.setState({value});
    }

    onSubmitForm = e => {
        e.preventDefault();
        const tries = this.state.tries;
        const ans = this.state.answer.join('')
        if(this.state.value === ans){
            this.setState({
                result: '홈런!',
                value: '',
                tries: [...tries, `${this.state.value}: 홈런!`],
            });
            alert('게임을 재시작합니다.');
            this.setState({
                value:'',
                answer: getNumbers(),
                tries: [],
                result:'',
            })
        } else {
            //볼, 스트라이크 판단
            let ball = 0;
            let strike = 0;

            if(this.state.tries.length >= 9){
                this.setState({
                    result : `10번 넘게 틀려서 실패! 정답은 ${ans} 였습니다`,
                    tries,
                });
                setTimeout(()=>{
                    alert('게임을 재시작합니다.');
                    this.setState({
                        value:'',
                        answer: getNumbers(),
                        tries: [],
                        result:'',
                    })
                },10);
            }else{
                for (let i = 0; i < this.state.value.length; i++) {
                    if (this.state.value[i] === ans[i]) {
                        strike++;
                    } else if (this.state.value.indexOf(ans[i]) > -1) {
                        ball++;
                    }
                }
                if(ball === 0 && strike === 0){ //out
                    tries.push(`${this.state.value}: OUT!`);
                }else{
                    tries.push(`${this.state.value}: ${strike}S ${ball}B`);
                }

                this.setState({
                    value: '',
                    result:'땡',
                    tries,
                });
            }

        }
        this.input.focus();
    }

    input;
    onRefInput = c =>{
        this.input = c;
    }
    fruits = [
        {fruit: '사과', taste:'맛없다.'},
        {fruit: '바나나', taste:'맛없다.'},
        {fruit: '호랑이', taste:'맛없다.'},
        {fruit: '구울', taste:'맛없다.'},
        {fruit: '구렁이', taste:'맛없다.'},
        {fruit: '고우와니', taste:'맛없다.'},
    ]

    render() {
        return (
            <>
                <h1>{this.state.result}</h1>
                <form onSubmit={this.onSubmitForm}>
                    <input type="text" maxLength={4} ref={this.onRefInput} value={this.state.value} onChange={this.onChangeInput}/>
                    <button>입력</button>
                </form>
                <div>시도: {this.state.tries.length}</div>
                <ul>
                    {
                        this.state.tries.map((v,i) => {
                            return (<Try key={v+i} value={v} index={i+1} />);
                        })
                    }
                </ul>
            </>
        );
    }
}
export default NumberBaseball;

NumberBaseball.jsx

 

import React, {Component} from "react";

class Try extends Component{
    render() {
        return (
        <li>
            {this.props.index}. <b>{this.props.value}</b>
        </li>
        );
    }
}
export default Try;

 

Try.jsx

리액트의 대부분의 문제는 props에서 발생한다.

자식의 자식에게 물려준다거나 더 깊이 들어가는 복잡한 경우가 생긴다.

그것을 방지하기 위해서 컨텍스트, 리덕스 같은 기술이 쓰인다.

(리액트에는 컨텍스트가 있고 컨텍스트가 좀 더 복잡한 일을 할 수 있게 만든 것이 리덕스(은행역할))

 

리액트 JSX 에서 주석처리하기

{/*<h1>{this.state.result}</h1>*/}

 

바인딩 부분은 영상을 보는게 나을 것 같다.

중요한 내용은 아니고 class 컴포넌트에서 화살표 함수를 쓰는 이유를 알려주심. (this를 신경쓰지 않기 위해서.. 화살표함수는 bind(this);를 자동으로해준다.)

 

+ Recent posts