인프런 커뮤니티 질문&답변

TaeHyeon Kim님의 프로필 이미지

작성한 질문수

웹 게임을 만들며 배우는 React

setTries를 하면 Cannot read properties of undefined (reading 'length') 에러가 뜹니다.

해결된 질문

21.11.04 21:53 작성

·

228

0

안녕하세요 제로초님. 항상 좋은 강의 감사드립니다.

유튜브로 강의 듣다가 3-8강에서 질문을 하기 위해 인프런 수강신청하여 질문 남깁니다. (유튜브는 질문댓글이 삭제되더라구요)

코드를 아래와 같이 작성하였는데, 리액트가 tries.length를 인식하지 못하는 현상이 발생합니다. tries 자체는 useState로 초기화해주었는데 tries.length의 length를 인식하지 못하는 이유가 무엇인가요? 문제 원인을 찾기 위해 setTries를 onChangeInput에 넣었을 때, 타이핑하자마자 바로 에러가 뜨는 걸로 봐선 tries를 setState할 때 에러가 발생하는 것 같은데 명확한 에러원인을 잘 모르겠습니다.

코드는 아래와 같습니다.

https://github.com/kth990303/TH-s-Web/issues/1

https://github.com/kth990303/TH-s-Web/tree/master/react-webgame/baseball

import React,{useState} from 'react';
import Try from './Try'
const getNumbers=()=>{
  const candidate=[1,2,3,4,5,6,7,8,9], ans=[];
  for(let i=0;i<4;i++){
    const chosen=candidate.splice(Math.floor(Math.random()*(9-i)), 1)[0];
    ans.push(chosen);
  }
  return ans;
}
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)=>{
        [...prevTries, {try:value, result:'홈런!'}]
      })
    }
    else{
      const answerArray=value.split('').map((v)=>parseInt(v));
      let strike=0, ball=0;
      if(tries.length>=9){
        setResult(`10번 넘게 틀려서 실패! 답은 ${answer.join(',')}였습니다!`);
        alert('게임을 다시 시작합니다.');
        setValue('');
        setAnswer(getNumbers());
        setTries([]);
      } else{
        for(let i=0;i<4;i++){
          if(answerArray[i]===answer[i]){
            strike++;
          } else if(answer.includes(answerArray[i])){
            ball++;
          }
        }
        setTries((prevTries)=>{
          [...prevTries, {try: value, result:`${strike}스트라이크 ${ball}볼입니다.`}]
        })
        setValue('');
      }
    }
  }

  const onChangeInput=(e)=>{
    console.log(tries.length);
    setValue(e.target.value);
  }

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

export default NumberBaseball;

 

감사합니다!

답변 1

1

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

2021. 11. 05. 11:04

setTries((prev) => (
  [...]
))

입니다.

( 대신 { 로 하셨습니다. (로 해야 return이 됩니다.

TaeHyeon Kim님의 프로필 이미지
TaeHyeon Kim
질문자

2021. 11. 05. 18:41

감사합니다. 해결했습니다!

항상 좋은 강의 감사합니다 :)