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

특별한 까치님의 프로필 이미지
특별한 까치

작성한 질문수

Redux vs MobX (둘 다 배우자!)

2-8. immer

immer 적용후 틱택토 초기화가 안됩니다

작성

·

208

1

틱택토에 이머 적용해 보았는데요

import React, { memouseStateuseReduceruseCallbackuseEffectuseRef } from 'react';
import Table from './Table';
import style from './TicTacToe.module.scss';
const { produce } = require('immer');

const initialState = {
  winner: '',
  turn: 'x',
  tableData: [
    ['','',''],
    ['','',''],
    ['','','']
  ],
  recentCell: [-1, -1]
}

const SET_WINNTER = 'SET_WINNER';
export const CLICK_CELL = 'CLICK_CELL';
const CHANGE_TURN = 'CHANGE_TURN';
const RESET_GAME = 'RESET_GAME';

const reducer = (stateaction=> {
  return produce(statedraft => {
    switch (action.type) {
      case SET_WINNTER:
        draft.winner = action.winner;
        break;
      case CLICK_CELL:
        draft.tableData[action.row][action.cell] = state.turn;
        draft.recentCell = [action.rowaction.cell];
        break;
      case CHANGE_TURN:
        draft.turn = state.turn === 'o' ? 'x' : 'o';
        break;
      case RESET_GAME:
        draft = {
          ...initialState,
          winner: state.winner
        }
        break;
      default:
        break;
    }
  });
}

function TikTakTo() {
  const [statedispatch] = useReducer(reducerinitialState);
  const { tableDataturnwinnerrecentCell } = state;
  // const [winner, setWinner] = useState('');
  // const [turn, setTurn] = useState('o');
  // const [tableData, setTableData] = useState([
  //   ['','',''],
  //   ['','',''],
  //   ['','','']
  // ]);

  useEffect(() => {
    const [rowcell] = recentCell;
    if(row < 0) {
      return;
    }
    //Game over
    let end = true;
    tableData.map(row => {
      row.map(cell => {
        if(cell === '') {
          end = false;
        }
      })
    });

    if(
        (tableData[row][0] === turn && tableData[row][1] === turn && tableData[row][2] === turn) ||
        (tableData[0][cell] === turn && tableData[1][cell] === turn && tableData[2][cell] === turn) ||
        (tableData[0][0] === turn && tableData[1][1] === turn && tableData[2][2] === turn) ||
        (tableData[0][2] === turn && tableData[1][1] === turn && tableData[2][0] === turn)
      ) {
        // 승리
        dispatch({
          type: SET_WINNTER,
          winner: turn
        });
        end = true;
    } else {
      dispatch({
        type: CHANGE_TURN
      });
    }
    
    if(end) {
      dispatch({
        type: RESET_GAME
      });
    }
  }, [recentCell]);

  const onClickTable = useCallback(
    () => {
      dispatch({
        type: SET_WINNTER,
        winner: 'o'
      });
    },
    [],
  )
  return (
    <>
      <Table
        onClick={onClickTable}
        tableData={tableData}
        dispatch={dispatch}
      ></Table>
      { winner && 
        <div className={style.result}>
          {winner}님의 승리
        </div>
      }
    </>
      
  )
}

export default memo(TikTakTo);

다른건 문제없이 작동하는데,  승리나 무승부 한 후에 테이블데이터 리셋 결과가 화면에 적용되지 않습니다. 리셋게임부분에 뭔가 코드를 잘못 적은걸까요..?

답변 5

1

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

draft.x = 'y' 같이 draft 내부 속성을 바꾸는 건 인식하는데

draft = 'z' 처럼 draft 자체를 바꾸는 건 인식 못합니다.

1

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

RESET_GAME쪽에 return draft 추가해보세요.

0

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

네 반대입니다.

0

아 immer안쓰는거랑 반대네요!!?

0

오 됩니다!! 근데 왜 리턴해주어야하는거죠?

다른 것들은 안해줘도 잘 동작하는데..

특별한 까치님의 프로필 이미지
특별한 까치

작성한 질문수

질문하기