본문 바로가기
패스트캠퍼스/자습

리액트 26~30강 정리

by sunnykim91 2019. 9. 18.

리액트에서는 push를 사용하지 않는다.

리액트에서는 뭐가 바꼈는지 감지를 하지 못한다.( = 랜더하지말아야지가 된다)

-> 스프레드 연산자를 사용한다.

 

 

구조분해 문법으로 this.state 나 this.props중복을 없앨 수 있음.

const { result, value, tries } = this.state;
        return (
            <>
                <h1>{result}</h1>  // this.state.result인데 this.state 생략가능

 

getNumbers() 를 밖에 사용하는 이유 : 혹시나 다른 곳에서 사용하기 위하여, 훅스로 바꿔도 영향 받지 않음.

 

redux, mobx를 사용하는 것이 깔끔하다. 부모와 자식간의 관계를 알기 위하여 

 

map은 1:1로 짝짓는 것이다.

 

개발 모드를 배포 모드를 바꾸려면, production으로 바꾸고, 맨위에 process.env.NODE_ENV = 'production' 을 추가.

 

 

훅스

// hooks
function getNumbers() { // 숫자 4개를 겹치지 않고 랜덤하게 뽑는 함수
    const candidate = [1,2,3,4,5,6,7,8,9];
    const array = [];
    for (let i = 0;i < 4; i += 1) {
        const chosen = candidate.splice(Math.floor(Math.random() * (9 - i)), 1)[0];
        array.push(chosen);
    }
    return array;
}

const NumberBaseball = () => {
    const [result, setResult] = useState('');
    const [value, setValue] = useState('');
    const [answer, setAnswer] = useState(getNumbers());
    const [tries, setTries] = useState([]);

    const onSubmitForm = (e) => {
        e.preventDefault();
        if (value === answer.join('')) {
            setResult('홈런!');
            setTries((prevTries) => {
                return [...prevTries, {try: value, result: '홈런!'}]
            });
            alert('게임을 다시 시작합니다.!');
            setValue('');
            setAnswer(getNumbers());
            setTries([]);
        } else {  // 답이 틀렸다면
            const answerArray = value.split('').map((v) => parseInt(v));
            let strike = 0;
            let ball = 0;
            if (tries.length >= 9) {
                setResult(`10번 넘게틀려서 실패! 답은 ${answer.join(',')}였습니다.`);
                alert('게임을 다시 시작합니다.!');
                setValue('');
                setAnswer(getNumbers());
                setTries([]);
            } else {
                for (let i = 0; i < 4; i+= 1) {
                    if (answerArray[i] === answer[i]) {
                        strike += 1;
                    } else if (answer.includes(answerArray[i])) {
                        ball += 1;
                    }
                }
                setTries((prevTries) => {
                    return [...prevTries, {try: value, result: `${strike} 스트라이크, ${ball} 볼 입니다.`}]
                });
                setValue('');
            }
        }
    }; 

    const onChangeInput = (e) => {
        console.log(answer);
        setValue(e.target.value);

    };

    return (
        <>
            <h1>{result}</h1>
            <form onSubmit={onSubmitForm}>
                <input maxLength={4} value={value} onChange={onChangeInput} />
            </form>
            <div>시도: {tries.length} </div>
            <ul>
                {tries.map((v, i) => {
                    return (
                        <Try key={`${i + 1}차 시도 :`} tryInfo={v} />
                    ); // return 생략가능   
                })}
            </ul>
        </>
    )
}

 

클래스형

class NumberBaseball extends Component {

    state = {
        result: '',
        value: '',
        answer: getNumbers(),  // ex: [1,3,5,7]
        tries: [],
    };

    onSubmitForm = (e) => {
        e.preventDefault();
        if (this.state.value === this.state.answer.join('')) {
            this.setState( (prevState) =>  {
                return {
                    result: '홈런!',
                    tries: [...prevState.tries, { try: this.state.value, result: '홈런!'}],
                }
            });
            alert('게임을 다시 시작합니다.!');
            this.setState({
                value: '',
                answer: getNumbers(),
                tries: [],
            });
        } else {  // 답이 틀렸다면
            const answerArray = this.state.value.split('').map((v) => parseInt(v));
            let strike = 0;
            let ball = 0;
            if (this.state.tries.length >= 9) {
                this.setState({
                    result: `10번 넘게틀려서 실패! 답은 ${answer.join(',')}였습니다.`,
                });
                alert('게임을 다시 시작합니다.!');
                this.setState({
                    value: '',
                    answer: getNumbers(),
                    tries: [],
                });
            } else {
                for (let i = 0; i < 4; i+= 1) {
                    if (answerArray[i] === this.state.answer[i]) {
                        strike += 1;
                    } else if (this.state.answer.includes(answerArray[i])) {
                        ball += 1;
                    }
                }
                this.setState((prevState) => {
                    return {
                        tries: [...prevState.tries, { try: this.state.value, result: `${strike} 스트라이크, ${ball} 볼 입니다.`}],
                        value: '',
                    }
                });
            }
        }
    }; 

    onChangeInput = (e) => {
        console.log(this.state.answer);
        this.setState({
            value: e.target.value,
        })

    };

    render() {
        const { result, value, tries } = this.state;
        return (
            <>
                <h1>{this.state.result}</h1>
                <form onSubmit={this.onSubmitForm}>
                    <input maxLength={4} value={this.state.value} onChange={this.onChangeInput} />
                </form>
                <div>시도: {this.state.tries.length} </div>
                <ul>
                    {this.state.tries.map((v, i) => {
                        return (
                            <Try key={`${i + 1}차 시도 :`} tryInfo={v} />
                        ); // return 생략가능   
                    })}
                </ul>
            </>
        )
    }
}

 

state, props가 바뀌어야만 렌더링이 된다.

setState만 호출하면 렌더링이 다시 일어남. 

 

이럴때 

shouldComponentUpdate 를 사용한다. (react에서 제공하는 메소드)

어떤 경우에만 렌더링을 다시 해줘야할지 적어줄 수 있는 역할을 함.

 

 

반응형

'패스트캠퍼스 > 자습' 카테고리의 다른 글

poiemaweb 14~15강 복습  (0) 2019.09.20
리액트 31~35강 정리  (0) 2019.09.19
리액트 21~25강 정리  (0) 2019.09.15
poiemaweb 8~9강 복습  (0) 2019.09.10
리액트 16~20강 정리  (0) 2019.09.09