저번 시간에는 gameTurns 상태를 작업했습니다
업데이트는 여기에서 이루어집니다
이 상태를 사용해서 게임판을
차례에 대한 배열에서 가져오겠습니다
그것을 위해 게임판 컴포넌트에
새로운 turns (차례) 속성을 전달하겠습니다
이름은 임의로 정하셔도 됩니다
여기에서 gameTurns 배열을
게임판에 대한 속성의 값으로 보내겠습니다
이제 게임판 컴포넌트에
이 turns 배열이 있을 것입니다
이 turns 속성은 배열입니다
이제 이 게임판 컴포넌트 함수에 로직을 더해서
게임판(gameBoard)을 가져와 보겠습니다
또한 중첩 배열입니다
즉, 이 turns 배열에서 나온 다차원적 배열입니다
이 turns 배열을 그런 성격으로 바꾸어야 합니다
어렵게 들리지만 간단한 작업입니다
간단한 부분에서 시작해 보겠습니다
여기에 gameBoard라는 변수를 추가하겠습니다
이 변수는 이후에 계속 사용하게 될 것입니다
이 아래쪽에서도 해당 변수를 호출하고 있습니다
이 게임판 변수는
초기 상태의 게임판입니다
그 초기 구조는 변하지 않기 때문입니다
하지만 이후에는 이 변수를 덮어씌울 것인데
나온 수가 있다면 turns에서 나온 데이터로 덮어씌울 것입니다
반대로 turns가 빈 배열이라면
게임판은 그대로 있을 것입니다
이것을 위해서는
여기에 루프(loop)를 추가하면 됩니다
turns를 반복하는 것인데
for과 of문을 사용해서 turns 속의 turns를 만들어냅니다 (중첩 구조)
만약 turns가 빈 배열이라면
우리 쪽에서 조치를 취하지 않는 이상 이 루프는 작동하지 않습니다
자바스크립트는 이렇게 작동하기 때문입니다
이 루프 안에서는 정보를 추출할 것인데
이미 나온 차례에 대한 정보입니다
그 정보는 이 배열에 저장한 객체에서 나옵니다
배열에 있는 각 차례가
이 구조의 객체가 됩니다
만약 정사각형(square) 속성을 가진 객체가
중첩 객체를 값으로 삼고
기호, 즉 player 속성을 가진
currentPlayer도 값으로 삼습니다
이 게임판에서 turns를 구조 분해 할당하여
square과 player라는 두 속성을 가지고 나오겠습니다
square과 property라는
이 두 속성을 turns에서 빼내겠습니다
현재 저희는 루프의 이 반복문을
이 구문을 가지고 보고 있습니다
말씀드린대로 square는
객체 속의 객체로서 (중첩 객체)
행(row)과 열(col) 속성을 가지고 있습니다
이 정보 또한 이 객체에서 빼내올 수 있습니다
여기에 square에서 row와 col을 가져왔습니다
즉 객체 구조 분해 할당을 두 번 실행하는 것입니다
이제 여기에 플레이어의 기호와
그 플레이어가 선택한 행과 열에 대한 값이 있습니다
이제 이 쪽의 게임판으로 돌아와서
행과 열을 플레이어 기호로 수정할 수 있습니다
이것으로 작업이 완료되었습니다
여기에서는 상태를 변경할 필요가 없습니다
대신 여기에서는 파생 상태를 다루고 있습니다
파생된 상태를 생성하고 있는 것인데
gameBoard는 계산된 값으로서
어떠한 상태에서 파생된 것입니다
이 경우에서는 이 gameTurns 상태에서 파생된 것으로
이 상태는 앱 컴포넌트에서 제어됩니다
gameBoard를 그 상태에서 파생시켜 오는 것입니다
이것이 리액트 내에서 사고하고 작업하는 방식입니다
제어하는 상태의 수는 최소화하되
각 상태에서 가능한 많은 정보와
많은 값을 파생시키는 것입니다
이대로 저장한 후에
앱을 재실행하겠습니다
버튼을 클릭해 보면 갑자기 모든 게 사라집니다
게임판이 사라진 것입니다
개발자 도구를 열어 보면 에러가 보입니다
"cannot set properties of undefined" 즉, 정의되지 않은 변수의 속성은 설정할 수 없다
확인해 보니 14번째 줄의 GameBoard가 문제가 있는 것 같습니다
이 줄에 문제가 있다는 것인데, 어떤 문제일까요?
여기서 한 발짝 뒤로 돌아가 보겠습니다
우리는 게임의 차례, gameTurns에 기반하여 게임판을 파생시킵니다
그렇다면 gameTurns로 돌아가 보겠습니다
gameTurns 상태는 여기에서 업데이트되고
여기에서 정보가 저장되는데
이 정보는 선택된 행과 열의 인덱스에 대한 정보입니다
그 데이터는 여기에서 받아서
handleSelectSquare 함수의 입력값으로 받고 있습니다
그렇다면 이 handleSelectSquare 함수는 어디로 호출되고 있습니까?
이 함수는 값으로서 전달되는데
onSelectSquare 속성을 통해 GameBoard로 전달됩니다
이 속성은 결국
onClick의 값으로 설정됩니다
그런데 onClick은 이것과 같이 행과 열에 대한 인덱스 데이터를 주지 않습니다
바로 이 부분이 문제점입니다
어떤 행과 어떤 열에 있는 버튼을 클릭했는지에 대한
해당 정보를 가져오기 위해서
다시 한 번 이 접근방식을 선택해야 합니다
이 방식은 이름 없는 함수를 만들어서
그 함수를 onClick으로 보냄으로써
onSelectSquare의 실행에 대한 통제권을 얻는 것입니다
즉 handleSelectSquare가 실행되는 방식에 대한 것입니다
여기에서 행에 대한 rowIndex와
열에 대한 colIndex를 이 함수의 인수로 보내겠습니다
즉 이 함수로 보내는 것입니다
이것이 onSelectSquare 속성의 값이기 때문입니다
이 작업을 통해서
데이터가 여기에 도착하고 저장되도록 했습니다
이제 새로고침을 해 보면
버튼을 클릭할 때 변동사항이 화면에 보입니다
여전히 같은 버튼을 여러 번 누를 수 있는 오류가 있지만
이것은 곧 고칠 예정입니다
현재로서는 게임 상태를 업데이트하되
gameTurns 상태에 기반하여서
이 계산값을 통해 업데이트하고 있습니다
이것은 곧 게임보드 컴포넌트의 파생 상태입니다
이제 이 gameTurns 상태를 사용해서
로그(log)를 반환할 수 있습니다
아주 유용한 실습이 될 작업인데
이 단계를 로그로 보내고 목록으로 반환하는 작업입니다
이 작업을 다음 시간에 같이 해 보겠습니다