리액트에서 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
'코딩이야기 > 인터넷 강의' 카테고리의 다른 글
section2. 3-8. 숫자야구 Hooks로 전환하기(+useState lazy init) (0) | 2024.05.22 |
---|---|
section2. 3-7 QnA (0) | 2024.05.21 |
section2. 3-5. 주석과 메서드 바인딩 (0) | 2024.05.20 |
section2. 3-4. 컴포넌트 분리와 props (0) | 2024.05.20 |
section2. 3-2. 리액트 반복문(map) + 3-3. 리액트 반복문(key) (0) | 2024.05.20 |