Я пытаюсь реализовать вариант «Ti c Ta c Toe» с React, который использует как Context
, чтобы обеспечить общее состояние для всего приложения и его дочерних компонентов («Store
»). ") и крюк редуктора (useReducer
). По сути, пытаясь go «Путь Redux» без Redux, используя эти новые инструменты React.
Теперь у состояния есть два элемента, один из которых представляет собой двумерный массив строк (3 строки 3 строковых столбца) с именем squares
, а другой - currentShape
- который должен содержать либо "X
", либо "O
"
При щелчке по квадрату отправляется действие squareClick
и (на данный момент) должен делать только эти две вещи:
- Устанавливает элемент в массиве
sqaures
, чтобы он стал state.currentShape
(предоставляя row & col). - Переключить
state.currentShape
на другую форму.
Вот так выглядит редуктор:
const SquareReducer = (state, action)=> {
switch (action.type) {
case 'squareClick':
let squares = state.squares;
squares[action.row][action.col] = state.currentShape;
return {
squares,
currentShape: (state.currentShape === "X" ? "O" : "X")
}
default:
return state;
}
}
Это компонент Square
:
const Square = ({row, col})=> {
const { appState } = useContext(StateContext);
const [state, dispatch] = useReducer(SquareReducer, appState);
return (
<div className="square"
onClick={()=> {
if (!state.squares[row][col]) {
dispatch({type:"squareClick", row, col});
}
}} >
{ appState.squares[row][col] }
</div>
)
}
Вот как компонент приложения написан и инициализирован:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
squares: [ ["", "", ""],
["", "", ""],
["", "", ""] ],
currentShape: "X"
}
this.squares =
<>
<Square row="0" col="0" />
<Square row="0" col="1" />
<Square row="0" col="2" />
<Square row="1" col="0" />
<Square row="1" col="1" />
<Square row="1" col="2" />
<Square row="2" col="0" />
<Square row="2" col="1" />
<Square row="2" col="2" />
</>
}
render() {
return (
<StateProvider value={{
appState: this.state,
setAppState: this.setState}}>
{ this.squares }
</StateProvider>
);
}
}
Теперь: неважно, что, когда нажимается квадрат:
Массив squares
равен обновлено, и если я укажу состояние из редуктора console.log - я всегда буду видеть самый обновленный, правильный squares
массив Но свойство currentShape
всегда сохраняет значение «X». Это так, , даже если я жестко закодирую «O» как значение (без условия).
Я не уверен, почему это происходит - с одной стороны, я могу видим, что редуктор предположительно получает обновленное состояние (массив sqaures
представлен справа) - с другой стороны, кажется, всегда сохраняет начальное значение для currentShape
.
Кто-нибудь есть идеи, почему?