This commit is contained in:
haerong22
2021-03-12 15:11:10 +09:00
4 changed files with 89 additions and 23 deletions

View File

@@ -1,7 +1,8 @@
import React from "react";
import React, {memo} from "react";
import Tr from "./Tr";
const Table = ({ onClick, tableData, dispatch }) => {
const Table = memo(({ tableData, dispatch }) => {
console.log("table rendered");
return (
<table>
{Array(tableData.length)
@@ -11,6 +12,6 @@ const Table = ({ onClick, tableData, dispatch }) => {
))}
</table>
);
};
});
export default Table;

View File

@@ -1,14 +1,24 @@
import React, { useCallback } from "react";
import { CLICK_CELL, CHANGE_TURN } from "./TicTacToe";
import React, { useCallback, useRef, useEffect, memo } from "react";
import { CLICK_CELL } from "./TicTacToe";
const Td = memo(({ rowIndex, cellIndex, dispatch, cellData }) => {
console.log("td rendered")
const ref = useRef([]);
useEffect(() => {
console.log(rowIndex === ref.current[0], cellIndex === ref.current[1], dispatch === ref.current[2], cellData === ref.current[3])
ref.current = [rowIndex, cellIndex, dispatch, cellData]
}, [rowIndex, cellIndex, dispatch, cellData])
const Td = ({ rowIndex, cellIndex, dispatch, cellData }) => {
const onClickTd = useCallback(() => {
console.log(rowIndex, cellIndex);
if(cellData) {
return;
}
dispatch({ type: CLICK_CELL, row: rowIndex, cell: cellIndex });
dispatch({ type: CHANGE_TURN });
});
}, [cellData]);
return <td onClick={onClickTd}>{cellData}</td>;
};
});
export default Td;

View File

@@ -1,4 +1,4 @@
import React, { useState, useReducer, useCallback } from "react";
import React, { useState, useEffect, useReducer, useCallback } from "react";
import Table from "./Table";
// 초기 state 값 설정
@@ -10,12 +10,14 @@ const initialState = {
["", "", ""],
["", "", ""],
],
recentCell: [-1, -1],
};
// action 이름 설정 - 하위 컴포넌트에서 사용하기 위해 모듈화
export const SET_WINNER = "SET_WINNER";
export const CLICK_CELL = "CLICK_CELL";
export const CHANGE_TURN = "CHANGE_TURN";
export const RESET_GAME = "RESET_GAME";
// reducer 설정 - dispatch 한 action 의 값들을 이용해 state 변경
const reducer = (state, action) => {
@@ -34,6 +36,7 @@ const reducer = (state, action) => {
return {
...state,
tableData,
recentCell: [action.row, action.cell]
};
}
// 칸을 클릭 할 때마다 O X 번갈아가면서 출력
@@ -43,17 +46,72 @@ const reducer = (state, action) => {
turn: state.turn === "O" ? "X" : "O",
};
}
case RESET_GAME: {
return {
...state,
turn: "O",
tableData: [
["", "", ""],
["", "", ""],
["", "", ""],
],
recentCell: [-1, -1],
}
}
default:
return state;
}
};
const TicTacToe = () => {
// useReducer 사용
const [state, dispatch] = useReducer(reducer, initialState);
const { tableData, turn, winner, recentCell } = state;
// 승자 체크
useEffect(() => {
const [row, cell] = recentCell;
if (row < 0) {
return;
}
let win = false;
if (tableData[row][0] === turn && tableData[row][1] === turn && tableData[row][2] === turn) {
win = true;
}
if (tableData[0][cell] === turn && tableData[1][cell] === turn && tableData[2][cell] === turn) {
win = true;
}
if (tableData[0][0] === turn && tableData[1][1] === turn && tableData[2][2] === turn) {
win = true;
}
if (tableData[0][2] === turn && tableData[1][1] === turn && tableData[2][0] === turn) {
win = true;
}
if (win) {
// 승자가 있을 때
dispatch({type:SET_WINNER, winner: turn})
dispatch({type:RESET_GAME});
} else {
// 무승부 일 때
let all = true; // all 이 true 면 무승부
tableData.forEach((row) => {
row.forEach((cell) => {
if(!cell) {
all = false;
}
})
});
if(all) { // 모든 칸이 다 차있으면 무승부
dispatch({type:RESET_GAME});
} else {
dispatch({ type: CHANGE_TURN });
}
}
}, [recentCell])
return (
<>
<Table tableData={state.tableData} dispatch={dispatch} />
{state.winner && <div>{state.winner}님의 승리</div>}
<Table tableData={tableData} dispatch={dispatch} />
{winner && <div>{winner}님의 승리</div>}
</>
);
};

View File

@@ -1,23 +1,20 @@
import React from "react";
import React, {memo, useMemo} from "react";
import Td from "./Td";
const Tr = ({ rowData, rowIndex, dispatch }) => {
const Tr = memo(({ rowData, rowIndex, dispatch }) => {
console.log("tr rendered")
return (
<tr>
{Array(rowData.length)
.fill()
.map((td, i) => (
<Td
rowIndex={rowIndex}
cellIndex={i}
dispatch={dispatch}
cellData={rowData[i]}
>
{""}
</Td>
useMemo(
() => <Td rowIndex={rowIndex} cellIndex={i} dispatch={dispatch} cellData={rowData[i]} >{""}</Td>,
[rowData[i]],
)
))}
</tr>
);
};
});
export default Tr;