Merge branch 'master' of https://github.com/haerong22/Study
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
import React from "react";
|
import React, {memo} from "react";
|
||||||
import Tr from "./Tr";
|
import Tr from "./Tr";
|
||||||
|
|
||||||
const Table = ({ onClick, tableData, dispatch }) => {
|
const Table = memo(({ tableData, dispatch }) => {
|
||||||
|
console.log("table rendered");
|
||||||
return (
|
return (
|
||||||
<table>
|
<table>
|
||||||
{Array(tableData.length)
|
{Array(tableData.length)
|
||||||
@@ -11,6 +12,6 @@ const Table = ({ onClick, tableData, dispatch }) => {
|
|||||||
))}
|
))}
|
||||||
</table>
|
</table>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
export default Table;
|
export default Table;
|
||||||
|
|||||||
@@ -1,14 +1,24 @@
|
|||||||
import React, { useCallback } from "react";
|
import React, { useCallback, useRef, useEffect, memo } from "react";
|
||||||
import { CLICK_CELL, CHANGE_TURN } from "./TicTacToe";
|
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(() => {
|
const onClickTd = useCallback(() => {
|
||||||
console.log(rowIndex, cellIndex);
|
console.log(rowIndex, cellIndex);
|
||||||
|
if(cellData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
dispatch({ type: CLICK_CELL, row: rowIndex, cell: cellIndex });
|
dispatch({ type: CLICK_CELL, row: rowIndex, cell: cellIndex });
|
||||||
dispatch({ type: CHANGE_TURN });
|
}, [cellData]);
|
||||||
});
|
|
||||||
|
|
||||||
return <td onClick={onClickTd}>{cellData}</td>;
|
return <td onClick={onClickTd}>{cellData}</td>;
|
||||||
};
|
});
|
||||||
|
|
||||||
export default Td;
|
export default Td;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useReducer, useCallback } from "react";
|
import React, { useState, useEffect, useReducer, useCallback } from "react";
|
||||||
import Table from "./Table";
|
import Table from "./Table";
|
||||||
|
|
||||||
// 초기 state 값 설정
|
// 초기 state 값 설정
|
||||||
@@ -10,12 +10,14 @@ const initialState = {
|
|||||||
["", "", ""],
|
["", "", ""],
|
||||||
["", "", ""],
|
["", "", ""],
|
||||||
],
|
],
|
||||||
|
recentCell: [-1, -1],
|
||||||
};
|
};
|
||||||
|
|
||||||
// action 이름 설정 - 하위 컴포넌트에서 사용하기 위해 모듈화
|
// action 이름 설정 - 하위 컴포넌트에서 사용하기 위해 모듈화
|
||||||
export const SET_WINNER = "SET_WINNER";
|
export const SET_WINNER = "SET_WINNER";
|
||||||
export const CLICK_CELL = "CLICK_CELL";
|
export const CLICK_CELL = "CLICK_CELL";
|
||||||
export const CHANGE_TURN = "CHANGE_TURN";
|
export const CHANGE_TURN = "CHANGE_TURN";
|
||||||
|
export const RESET_GAME = "RESET_GAME";
|
||||||
|
|
||||||
// reducer 설정 - dispatch 한 action 의 값들을 이용해 state 변경
|
// reducer 설정 - dispatch 한 action 의 값들을 이용해 state 변경
|
||||||
const reducer = (state, action) => {
|
const reducer = (state, action) => {
|
||||||
@@ -34,6 +36,7 @@ const reducer = (state, action) => {
|
|||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
tableData,
|
tableData,
|
||||||
|
recentCell: [action.row, action.cell]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// 칸을 클릭 할 때마다 O X 번갈아가면서 출력
|
// 칸을 클릭 할 때마다 O X 번갈아가면서 출력
|
||||||
@@ -43,17 +46,72 @@ const reducer = (state, action) => {
|
|||||||
turn: state.turn === "O" ? "X" : "O",
|
turn: state.turn === "O" ? "X" : "O",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
case RESET_GAME: {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
turn: "O",
|
||||||
|
tableData: [
|
||||||
|
["", "", ""],
|
||||||
|
["", "", ""],
|
||||||
|
["", "", ""],
|
||||||
|
],
|
||||||
|
recentCell: [-1, -1],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const TicTacToe = () => {
|
const TicTacToe = () => {
|
||||||
// useReducer 사용
|
// useReducer 사용
|
||||||
const [state, dispatch] = useReducer(reducer, initialState);
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<Table tableData={state.tableData} dispatch={dispatch} />
|
<Table tableData={tableData} dispatch={dispatch} />
|
||||||
{state.winner && <div>{state.winner}님의 승리</div>}
|
{winner && <div>{winner}님의 승리</div>}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
import React from "react";
|
import React, {memo, useMemo} from "react";
|
||||||
import Td from "./Td";
|
import Td from "./Td";
|
||||||
|
|
||||||
const Tr = ({ rowData, rowIndex, dispatch }) => {
|
const Tr = memo(({ rowData, rowIndex, dispatch }) => {
|
||||||
|
console.log("tr rendered")
|
||||||
return (
|
return (
|
||||||
<tr>
|
<tr>
|
||||||
{Array(rowData.length)
|
{Array(rowData.length)
|
||||||
.fill()
|
.fill()
|
||||||
.map((td, i) => (
|
.map((td, i) => (
|
||||||
<Td
|
useMemo(
|
||||||
rowIndex={rowIndex}
|
() => <Td rowIndex={rowIndex} cellIndex={i} dispatch={dispatch} cellData={rowData[i]} >{""}</Td>,
|
||||||
cellIndex={i}
|
[rowData[i]],
|
||||||
dispatch={dispatch}
|
)
|
||||||
cellData={rowData[i]}
|
|
||||||
>
|
|
||||||
{""}
|
|
||||||
</Td>
|
|
||||||
))}
|
))}
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
export default Tr;
|
export default Tr;
|
||||||
|
|||||||
Reference in New Issue
Block a user