React - Zerocho (webGame)
2.구구단
리액트로 구구단 게임을 만들어보자!
아래 내용은 zeroCho님의 강좌를 기본으로 합니다.
리액트에서는 바뀌는 부분을 state로 한다.
바뀌는 부분을 이해한다는건 리액트에서 굉장히 중요하다.
구구단 게임에서 바뀌는것을 생각해보자
- 문제 부분( 5 곱하기 4 는?) 에서 5부분 과 4부분
- 사용자가 답을 입력할 인풋
- 그리고 문제 결과를 알려줄 '정답' 과 '땡' 부분
(1)<div>5 곱하기 4 는?</div>
(2)<input type="number" value="value"/>
<button type="submit">입력</button>
(3)<div>"땡","정답"</div>
바뀌는 부분을 state에 넣어보자
constructor(props) {
super(props);
this.state = {
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
//frist,second가 첫번째 숫자와 두번째 숫자
value: '',
//input의 결과입력
result: ''
//땡,정답을 표시해줄 result
}
}
state를 다 지정했으니 이제는 render부분을 작성해 보자
rander(){
return(
<React.Fragment>
<div>{ this.state.first } 곱하기 { this.state.second } 는?</div>
<form>
<input type="number" value={this.state.value} />
<button type="submit">입력</button>
</form>
<div>{ this.state.resultNumber } { this.state.result }</div>
</React.Fragment>
)
}
지정해둔 state를 가지고 위와 같이 입력한다.
저 상태로 실행하면 input에 아무것도 입력이 안된다.
rander(){
return(
<React.Fragment>
<div>{ this.state.first } 곱하기 { this.state.second } 는?</div>
<form onSubmit={ this.onSubmit }>
<input type="number" value={this.state.value} onChange={ this.onChange } />
<button type="submit">입력</button>
</form>
<div>{ this.state.resultNumber } { this.state.result }</div>
</React.Fragment>
)
}
from에 onSubmit 과 input에 onChange를 넣고 그 안에 함수를 넣어준다.
onSubmit = (e)=> {
e.preventDefault();
if (parseInt(this.state.value) === this.state.first * this.state.second ) {
//정답 화면
this.setState({
result: this.state.first * this.state.second + ' 정답',
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 });
}
onSubmit은 사용자가 입력한 값을 정답과 비교해서 result에 틀렸을땐 "땡",맞췄을때는 "정답"을 표시하도록 하는것이다.
함수를 작성할때는 화살표 함수를 사용한다.(이유는 this때문이며 function으로 작성시 .bind(this)를 해줘야 하기 때문이다.)
if (parseInt(this.state.value) === this.state.first * this.state.second) {
//정답 화면
this.setState({
result: this.state.first * this.state.second + ' 정답',
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
value: ''
});
} else {
//오답 화면
this.setState({
result: '땡',
value: ''
});
}
조건문으로 사용자가 입력한 값(parseInt(this.state.value))과 this.state.first * this.state.second 를 비교한다.
조건문에서 parseInt()는 문자열을 수로 바꾸는 함수이다.
https://www.codingfactory.net/11026
이 부분을 모르면 위 링크를 참고하자!
사용자 입력값 === 답 을 비교하고 정답화면일때 state와 오답일때 state 변경을 입력해준다.
this.setState({})로 바꾸고 싶은 state를 입력해준다.
리엑트에서는 state를 변경하고 싶으면 this.setState({})를 사용한다. (이유는 나중에 따로 설명)
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: ''
}
}
// 아래 처럼도 가능하며 실무에서 많이 사용
// 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: this.state.first * this.state.second + ' 정답',
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를 감싸줘야 했지만 <></>(바벨2) or <React.Fragment></React.Fragment>(바벨)로 하면 div가 사라진다.
<React.Fragment>
<div>{ this.state.first } 곱하기 { this.state.second } 는?</div>
<form onSubmit={ this.onSubmit }>
<input type="number" value={this.state.value} onChange={ this.onChange } />
<button type="submit">입력</button>
</form>
<div>{ this.state.resultNumber } { this.state.result }</div>
</React.Fragment>
);
}
}
위에 한 작업을 총 정리해보면
- 바뀌는 부분을 state로 정한다.
- render()메소드에 DOM을 작성한다.
- 필요한 함수를 작성하고 필요한 부분에 넣어준다.
- 직접 만든 함수는 화살표 함수(e)=> 를 써야한다. this때문인데 .bind(this)를 써야하니깐 화살표 함수를 사용
- render()메소드로 DOM작성시 단 하나의 DDOM 요소를 반환해야 하지만 HTML에서 봤을때 쓸데없는 <div> 가 생기는거기 때문에 불편한 요소이다. 그렇기 때문에 <></> 와 <React.Fragment></React.Fragment> 등으로 감싸주면 HTML에서는 div로 나오지 않는다.